使用exec执行含自定义类型的Python代码时报错,原因是什么?
问题原因
当你调用 exec() 时传入两个独立的字典(gl 作为全局命名空间,lo 作为局部命名空间),Python 会将执行代码中未声明为 global 的名称(比如 Result 类)存储在**局部命名空间 lo中,但在执行代码里定义的函数(比如 multiply)会把你传入的全局命名空间 gl**作为自身的全局作用域。
所以当 multiply 函数尝试创建 Result 对象时,它会在 gl 中查找 Result,但 gl 是空的,自然就抛出了 NameError。
解决方法
方法1:使用同一个命名空间作为全局和局部
不要分开传入两个独立的字典,让全局和局部命名空间指向同一个字典:
from pathlib import Path ns = {} exec(Path("multiply.py").read_text(), ns, ns)
这样所有名称(包括 Result 和 multiply)都会存入同一个命名空间,multiply 函数就能正常找到 Result 类了。
方法2:不指定局部命名空间
如果只传入全局命名空间,Python 会自动用它作为局部命名空间,效果和方法1一致:
from pathlib import Path gl = {} exec(Path("multiply.py").read_text(), gl)
额外说明
你并不是不能在 exec 中创建新类型,问题出在命名空间的分离导致作用域不匹配。只要让函数和它依赖的类处于同一个全局作用域,就能正常运行。
内容的提问来源于stack exchange,提问作者grześ
相关产品推荐
相关产品推荐

