2016-06-18 162 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