2016-06-18 4 views
4

私はカスタムPythonインタプリタ型アプリケーションを作成しようとしています。私は与えられたコードを実行するためにexec文(Python 2.7.6)を使用していますが、グローバルは期待通りに動作しません。誰かがこれが動作しない理由を説明してもらえ:Python execでglobalsを使用する

def print_x(): 
    print(x) 


g = {'x': 10, 'print_x': print_x} 
l = {} 

exec('print_x()', g, l) 

は結果(print_x関数はGまたはLであるかどうか)、エラーである:だから

NameError: global name 'x' is not defined 

、グローバルではないのexecに渡しません呼び出された関数に引き継ぐ?

+0

だからexecはあなたの辞書を構文解析する方法を知らないg – dmitryro

+0

しかし、私はexec( 'print(x)'、g、l)を使っても問題ありません。これはprint_x関数では機能しません。 – jordanwh

+0

http://stackoverflow.com/questions/2904274/globals-and-locals-in-python-exec - あなたのケースに似ています – dmitryro

答えて

3

関数内のxは、関数が定義されている名前空間のグローバルから選択されます。しかし、あなたは別の名前空間でそれを呼び出すことになります。これは、複数のモジュールを有するからあまりにも異なるされていません。最終的には、gexecの実行コンテキストではグローバルである

# bar.py 
from foo import print_x 

x = 10 
print_x() # NameError 

# foo.py 
def print_x(): 
    print(x) 

し、別のモジュールでそれを使用しようとしています。 print_x関数(別のグローバルコンテキストで定義されています)を呼び出した後、print_xはexecの実行コンテキスト内のグローバルについて何も知りません。print_xはモジュールのコンテキスト内のグローバルのみを認識します。

+0

よろしくお願いいたします。ですから、私はexecを使ってprint_x()関数を定義する必要がありますか?関数の名前空間を変更する他の方法はありますか? – jordanwh

+0

@jordanwh実際にあなたが[関数のコピー]を作成することができるグローバルを変更したい場合(http://stackoverflow.com/questions/13503079/how-to-create-a-copy-of-a-python-関数)を使用して、新しい関数のグローバルに渡されます。 –

+0

@jordanwh - 私は、 'types.FunctionType'やそれに類するものを使って新しい関数を作成した古い関数をいくつか(おそらくcpython固有の)見たことがあると思います。私は頭の上からそれをやる方法を知らないので、もしあなたが本当にそれを働かせようとしているのであれば、あなたはおそらく何らかの酔いどれをする必要があります。 – mgilson

関連する問題