Python的C API函數PyEval_EvalCode
讓我們在執行編譯Python代碼中運行Python代碼。我想執行一段Python代碼,就好像它在函數的範圍內執行一樣,以便它具有自己的不影響全局狀態的局部變量字典。C Python而:上下文
這似乎很容易做到,因爲PyEval_EvalCode
讓你提供一個全局和局部字典:
PyObject* PyEval_EvalCode(PyCodeObject *co, PyObject *globals, PyObject *locals)
我碰上了與Python如何查找變量名做的問題。考慮下面的代碼,我跟PyEval_EvalCode
執行:
myvar = 300
def func():
return myvar
func()
這個簡單的代碼實際上提出了一個錯誤,因爲Python是無法找到變量myvar
從func
內。即使myvar
位於外部作用域的本地字典中,Python也不會將其複製到內部作用域的本地字典中。原因如下:
每當Python查找變量名時,首先檢查locals
,然後檢查globals
,最後檢查builtins
。在模塊範圍,locals
和globals
是相同的字典對象。因此,在模塊範圍內聲明x = 5
將放置x
在該locals
字典,這也是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