我遇到的问题是,在exec语句中的模块级别创建的变量不能从同一模块中定义的函数访问.
假设你有以下Python程序:
x = 5 def foo(): print x foo()
如果将上述四行放在一个文件中并运行它,那么它将无所谓.
但是,如果您尝试从exec语句中运行相同的代码,它将无法正常工作.
这是我们以前的程序,在一个exec语句里面:
import __builtin__ global_env = {'__builtins__': __builtin__} local_env = dict() exec """ x = 5 def foo(): print x foo() """ in global_env,local_env
执行时,而不是工作,它会产生以下错误:
Traceback (most recent call last): File "lab.py",line 94,in <module> """ in global_env,local_env File "<string>",line 5,in <module> File "<string>",line 4,in foo NameError: global name 'x' is not defined
我认为模块级变量存储在全局范围内,但似乎至少在exec中,它们不是.
例如,在上一个示例中,如果将foo()的调用替换为:
print global_env print local_env
你得到:
{'__builtins__': <module '__builtin__' (built-in)>} {'x': 5,'foo': <function foo at 0x102c12938>}
所以在模块级(包括x)中定义的任何东西都存储在本地()中.
但是除了exec语句的模块级以外,从任何地方访问x是不可能的.特别是,如上所述,x的本地范围对同一个exec语句中定义的函数是不可见的.
第一个在函数中使用全局关键字:
exec """ x = 5 def foo(): global x print x foo() """ in global_env,local_env
第二个在exec中使用与全局变量()和locals()相同的字典:
exec """ x = 5 def foo(): print x foo() """ in global_env
所以我的问题是:为什么exec中的模块级变量存储在本地,为什么从模块级到任何地方都不可访问?
一些密切相关的StackOverflow帖子:
> globals and locals in python exec()
> Cannot change global variables in a function through an exec() statement?
解决方法
If two separate objects are given as globals and locals,the code will be executed as if it were embedded in a class definition.
这意味着本地的赋值将变成本地命名空间(相当于类级变量),但如果函数(即方法)尝试引用本地(类)变量,则不会成为闭包.
将您的代码与:
class Test(object): x = 1 def foo(): print x foo()
同样的原因,你会得到同样的错误. foo不是一个闭包,所以它尝试在全局命名空间(不成功)中引用x.