为什么 Python 3 exec() 在指定局部变量时会失败?
Why does Python 3 exec() fail when specifying locals?
下面的代码在Python 3 中没有错误地执行:
code = """
import math
def func(x):
return math.sin(x)
func(10)
"""
_globals = {}
exec(code, _globals)
但是如果我也尝试捕获局部变量 dict,它会失败并显示 NameError
:
>>> _globals, _locals = {}, {}
>>> exec(code, _globals, _locals)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-9-aeda81bf0af1> in <module>()
----> 1 exec(code, {}, {})
<string> in <module>()
<string> in func(x)
NameError: name 'math' is not defined
为什么会这样,如何在捕获全局变量和局部变量的同时执行这段代码?
Remember that at module level, globals and locals are the same dictionary. If exec
gets two separate objects as globals and locals, the code will be executed as if it were embedded in a class definition.
您传入了两个单独的字典,但试图执行需要模块范围全局变量可用的代码。 class 中的 import math
会产生一个 局部作用域属性 ,而您创建的函数将无法访问它作为 class 作用域名称不考虑函数闭包。
参见 Python 执行模型参考中的 Naming and binding:
Class definition blocks and arguments to exec()
and eval()
are special in the context of name resolution. A class definition is an executable statement that may use and define names. These references follow the normal rules for name resolution with an exception that unbound local variables are looked up in the global namespace. The namespace of the class definition becomes the attribute dictionary of the class. The scope of names defined in a class block is limited to the class block; it does not extend to the code blocks of methods[.]
您可以通过尝试执行 class 定义中的代码来重现错误:
>>> class Demo:
... import math
... def func(x):
... return math.sin(x)
... func(10)
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in Demo
File "<stdin>", line 4, in func
NameError: name 'math' is not defined
只需传入一个字典即可。
下面的代码在Python 3 中没有错误地执行:
code = """
import math
def func(x):
return math.sin(x)
func(10)
"""
_globals = {}
exec(code, _globals)
但是如果我也尝试捕获局部变量 dict,它会失败并显示 NameError
:
>>> _globals, _locals = {}, {}
>>> exec(code, _globals, _locals)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-9-aeda81bf0af1> in <module>()
----> 1 exec(code, {}, {})
<string> in <module>()
<string> in func(x)
NameError: name 'math' is not defined
为什么会这样,如何在捕获全局变量和局部变量的同时执行这段代码?
Remember that at module level, globals and locals are the same dictionary. If
exec
gets two separate objects as globals and locals, the code will be executed as if it were embedded in a class definition.
您传入了两个单独的字典,但试图执行需要模块范围全局变量可用的代码。 class 中的 import math
会产生一个 局部作用域属性 ,而您创建的函数将无法访问它作为 class 作用域名称不考虑函数闭包。
参见 Python 执行模型参考中的 Naming and binding:
Class definition blocks and arguments to
exec()
andeval()
are special in the context of name resolution. A class definition is an executable statement that may use and define names. These references follow the normal rules for name resolution with an exception that unbound local variables are looked up in the global namespace. The namespace of the class definition becomes the attribute dictionary of the class. The scope of names defined in a class block is limited to the class block; it does not extend to the code blocks of methods[.]
您可以通过尝试执行 class 定义中的代码来重现错误:
>>> class Demo:
... import math
... def func(x):
... return math.sin(x)
... func(10)
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in Demo
File "<stdin>", line 4, in func
NameError: name 'math' is not defined
只需传入一个字典即可。