为什么我不能在另一个函数中的 exec 中声明一个函数?我真的不知道为什么会这样,有没有办法让它工作。我发现了这个:Invoking problem with defined in exec()但这并不是我想要的,在我的情况下,我不希望 exec 代码是任意的。
def test():
exec("""
def this():
print('this')
def main():
this()
main()
""")
test()
回报:
Traceback (most recent call last):
File "/t.py", line 12, in <module>
test()
File "/t.py", line 2, in test
exec("""
File "<string>", line 8, in <module>
File "<string>", line 6, in main
NameError: name 'this' is not defined
当我在函数之外执行 exec 时,它工作得很好,为什么?:
exec("""
def this():
print('this')
def main():
this()
main()
""")
TLDR:提供显式的全局字典来执行代码“就好像”它在顶层运行一样。
Python 使用词法作用域,这大致意味着根据源代码中的嵌套查找名称。例如,嵌套函数可以访问外部函数的变量。
def foo():
bar = 12
def qux():
print(bar) # nested scope accesses outer scope
return qux
值得注意的是,这种名称查找发生在源代码编译时——编译器知道这两者foo
和qux
访问bar
,所以它必须对两者都可用。内层函数直接编译看外层函数的变量。
相反,如果一个函数没有嵌套,它对非局部变量的名称查找会自动进入全局范围。
def qux():
print(bar) # top-level scope accesses global scope
当我们在函数中编码时,这是一个问题exec
:一个定义如被编译为在全局范围内def main(): this()
查找,但在函数的当前本地范围内运行。this
exec
在所有情况下,如果省略了可选部分,则代码将在当前范围内执行。
因此,全局查找this
但在本地定义。1编译器分别解析和 exec 代码,因此它不知道查找意味着被视为嵌套。结果,查找失败。def test
为了exec
编码“好像”它在顶层运行,提供一个显式的就足够了globals
——例如一个新的命名空间{}
或实际的globals()
.
def test():
exec("""
def this():
print('this')
def main():
this()
main()
""", {})
# ^^ globals namespace for exec
test()
这意味着代码现在在(它自己的)全局命名空间中运行,这也是函数查找搜索的地方。
1这可以通过打印globals()
/locals()
和检查功能说明来检查。dis.dis(main)
在 exec 中会产生:
6 0 LOAD_GLOBAL 0 (this)
2 CALL_FUNCTION 0
4 POP_TOP
6 LOAD_CONST 0 (None)
8 RETURN_VALUE
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句