Python C API関数PyEval_EvalCode
コンパイル済みのPythonコードを実行しましょう。私はPythonコードのブロックを、関数のスコープ内で実行しているかのように実行したいので、グローバル状態に影響を与えないローカル変数の辞書を持っています。C Python:コンテキスト内でのPythonコードの実行
PyEval_EvalCode
あなたは、グローバルとローカル辞書を提供することができますので、これは、行うのに十分に簡単そうです:
PyObject* PyEval_EvalCode(PyCodeObject *co, PyObject *globals, PyObject *locals)
私はに実行し、問題はPythonは変数名を検索する方法に関係しています。私はPyEval_EvalCode
で実行することを、次のコードを考えてみましょう:Pythonはfunc
内から変数myvar
を見つけることができないため
myvar = 300
def func():
return myvar
func()
この単純なコードでは、実際に、エラーが発生します。 myvar
は外側のスコープ内のローカルディクショナリにありますが、Pythonはそれを内部スコープ内のローカルディクショナリにコピーしません。これは、次のとおりです。
Pythonが変数名を検索すると、まずlocals
がチェックされ、次にglobals
がチェックされ、最後にbuiltins
がチェックされます。 モジュールスコープでは、locals
とglobals
がSAMEディクショナリオブジェクトです。したがって、モジュールスコープの文x = 5
は、locals
辞書にx
という辞書を配置します。globals
辞書でもあります。今度は、モジュールスコープで定義された関数x
は、関数スコープlocals
内でx
を見つけられません。なぜなら、Pythonはモジュールスコープのローカルを関数スコープのローカルにコピーしないからです。しかし、これは通常、問題ありません。x
がglobals
にあるためです。
x = 5
def foo():
print(x) # This works because 'x' in globals() == True
これは、Pythonが内部スコープの地元の人々に外側スコープの地元の人々をコピーするように見えることだけでネストされた機能です。 (また、彼らは、内側範囲内で必要とされている場合のみ、遅延しそうに思われる。)
def foo():
x = 5
def bar():
print(x) # Now 'x' in locals() == True
bar()
だから、このすべての結果はモジュールスコープでコードを実行するときに、あなたがしなければならない、ということですグローバルディクショナリとローカルディクショナリがSAMEオブジェクトであることを確認してください。さもなければ、モジュールスコープ関数はモジュールスコープ変数にアクセスすることができません。
私の場合は、グローバル辞書とローカル辞書を同じにすることは望ましくありません。だから私は関数スコープでコードを実行していることをPythonインタプリタに伝える何らかの方法が必要です。これを行うにはいくつかの方法がありますか?私はPyCompileFlags
と追加の引数であるPyEval_EvalCodeEx
を調べましたが、これを行う方法は見つかりませんでした。
@ Channel72上記を参照してください。 – ecatmur