3

サイトを検索しようとしましたが、私の問題に対する答えが見つかりません:

mymodule.pyという名前のモジュールがあり、次のものが含まれているとします。

def a():
    return 3

def b():
    return 4 + a()

次に、次のように動作します。

import mymodule
print(mymodule.b())

ただし、モジュールの内容を動的に定義しようとすると、次のようになります。

import imp

my_code = '''
def a():
    return 3

def b():
    return 4 + a()
'''

mymodule = imp.new_module('mymodule')
exec(my_code, globals(), mymodule.__dict__)
print(mymodule.b())

次に、関数b()で失敗します。

Traceback (most recent call last):
File "", line 13, in <module>
File "", line 6, in b
NameError: global name 'a' is not defined

モジュール内の階層的な名前空間検索を保持する方法が必要です。これは、モジュールがディスク上に存在しない限り失敗するようです。

違いは何ですか?

ありがとう、ロブ。

4

2 に答える 2

3

あなたは近くにいます。execにそのような別の名前空間で動作するように指示する必要があります(python 3.xについては下部の注を参照してください)。

exec my_code in mymodule.__dict__

完全な例:

import imp

my_code = '''
def a():
    return 3

def b():
    return 4 + a()
'''

mymodule = imp.new_module('mymodule')

exec my_code in mymodule.__dict__
print(mymodule.b())

そうは言っても、私はこれを以前に使用したことがないので、これに奇妙な副作用があるかどうかはわかりませんが、私にはうまくいくようです。

また、ここのpythonドキュメントに「execin ...」に関する小さな宣伝文句があります:http://docs.python.org/reference/simple_stmts.html#the-exec-statement

アップデート

元の試行が正しく機能しなかった理由は、現在のモジュールのglobals()ディクショナリを渡していたためです。これは、新しいモジュールが使用する必要のあるglobals()とは異なります。

このexec行も機能します(ただし、「exec in ...」スタイルほどきれいではありません):

exec(my_code, mymodule.__dict__, mymodule.__dict__)

更新2: execはpython 3.xの関数になっているため、「exec in ...」スタイルがないため、上記の行を使用する必要があります。

于 2012-06-27T03:59:02.237 に答える
0

それは、exec()使用するように設計されている方法ではありません。exec()実行するコードを実際にモジュールに「挿入」するのではなく、呼び出し元のモジュール空間で実行しますexec()

于 2012-06-27T03:45:25.083 に答える