jak*_*vdp 11 python exec python-3.x python-exec
以下在Python 3中执行时没有错误:
code = """
import math
def func(x):
return math.sin(x)
func(10)
"""
_globals = {}
exec(code, _globals)
Run Code Online (Sandbox Code Playgroud)
但是,如果我尝试捕获局部变量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
Run Code Online (Sandbox Code Playgroud)
为什么会发生这种情况,如何在捕获全局变量和局部变量时执行此代码?
Mar*_*ers 13
从exec()文档:
请记住,在模块级别,全局变量和本地变量是相同的字典.如果
exec获得两个单独的对象作为全局变量和局部变量,则代码将被执行,就像它嵌入在类定义中一样.
您传入了两个单独的词典,但尝试执行需要模块范围全局变量的代码.import math在类中会生成一个本地范围属性,并且您创建的函数将无法访问它,因为类范围名称不考虑函数闭包.
请参阅Python执行模型参考中的命名和绑定:
类定义块和参数
exec(),并eval()在名称解析的情况下特别.类定义是可以使用和定义名称的可执行语句.这些引用遵循名称解析的常规规则,但在全局命名空间中查找未绑定的局部变量.类定义的名称空间成为类的属性字典.类块中定义的名称范围仅限于类块; 它没有扩展到方法的代码块[.]
您可以通过尝试在类定义中执行代码来重现错误:
>>> 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
Run Code Online (Sandbox Code Playgroud)
只需传入一本字典.