2016-06-18 110 views
4

我正在嘗試創建一個自定義python解釋器類型的應用程序。我使用exec語句(在Python 2.7.6中)來執行給定的代碼,但全局變量沒有按預期的那樣工作。可能有人解釋爲什麼這不起作用:在Python中使用全局變量exec

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是從函數定義的命名空間的全局變量中提取出來的。但是,您在不同的名稱空間中調用它。這不是從具有多個模塊也不同:

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

,然後試圖用不同模塊使用它:

# bar.py 
from foo import print_x 

x = 10 
print_x() # NameError 

最終,g處於exec執行上下文的全局變量。在調用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 - 我想我已經看到一些(可能是特定於cpython的)解決方案,它們使用'types.FunctionType'或類似的東西創建一個新的函數。我不知道該怎麼做,因此你可能需要做一些調查,如果你真的想讓它工作... – mgilson