8

eval() を使用していくつかの関数を実行しようとしていますが、それらを実行するための何らかの環境を作成する必要があります。ドキュメントには、グローバルを 2 番目のパラメーターとして eval() に渡すことができると記載されています。

しかし、私の場合はうまくいかないようです。簡略化した例を次に示します (変数グローバルを宣言し、globals() を使用するという 2 つのアプローチを試しましたが、どちらも機能しません)。

ファイルscript.py :

import test

global test_variable
test_variable = 'test_value'
g = globals()
g['test_variable'] = 'test_value'
eval('test.my_func()', g)

ファイルtest.py :

def my_func():
    global test_variable
    print repr(test_variable)

そして、私は得ています:

NameError: グローバル名 'test_variable' が定義されていません。

test_variableそれをに渡すにはどうすればよいmy_func()ですか?パラメータとして渡すことができないと仮定します。

4

2 に答える 2

10

test_variableは test.pyでグローバルにする必要があります。まだ存在しないグローバル変数を宣言しようとしているため、名前エラーが発生しています。

したがって、 my_test.py ファイルは次のようになります。

test_variable = None

def my_func():
    print test_variable

コマンドプロンプトからこれを実行します:

>>> import my_test
>>> eval('my_test.my_func()')
None
>>> my_test.test_variable = 'hello'
>>> my_test.test_variable
'hello'
>>> eval('my_test.my_func()')
hello

一般に、eval() とグローバルを使用するのは悪い形式なので、自分が何をしているのかを確認してください。

于 2009-04-08T09:32:51.280 に答える
4

私が間違っている場合は、Python の専門家に訂正してください。Pythonも学んでいます。NameError以下は、例外がスローされた理由についての現在の理解です。

Python では、モジュール名を指定せずにモジュール間でアクセスできる変数を作成することはできません (つまり、モジュール内で使用する必要があるモジュール内のグローバル変数にアクセスするにはtest) 。グローバル変数のスコープは、モジュール自体にかなり限定されています。mod1mod1.testmod2

したがって、次の場合test.py

def my_func():
    global test_variable
    print repr(test_variable)

test_variablehere は(test.test_variableつまりtest_variabletestモジュールの名前空間で) を参照します。

したがって、変数を名前空間に設定test_variableするscript.pyと、変数が__main__名前空間に配置されます (__main__これは、実行するために Python インタープリターに提供したトップレベルのモジュール/スクリプトであるため)。したがって、これtest_variableは別の名前空間にあり、test必要なモジュールの名前空間にはありません。したがって、Python は、モジュールのグローバル名前空間と組み込み名前空間をNameError検索しても変数が見つからないため、 を生成します (ステートメントのためにローカル関数名前空間はスキップされます)。testglobal

したがって、 を機能させるには、モジュールの名前空間を次のevalように設定する必要があります。test_variabletestscript.py

import test
test.test_variable = 'test_value'
eval('test.my_func()')

Python のスコープと名前空間の詳細については、http: //docs.python.org/tutorial/classes.html#python-scopes-and-name-spacesを参照してください。

于 2009-04-08T10:44:36.287 に答える