在函数内调用exec执行代码时出现Typing List未定义问题求助
问题原因分析
你的代码执行失败的核心原因是函数内exec的命名空间限制与类定义的作用域查找规则冲突:
当在foo函数中调用exec(code)且不指定globals和locals参数时,Python会默认使用函数的局部命名空间作为exec的局部命名空间。但Python函数的局部变量是编译期静态确定的,exec无法直接向这个命名空间中添加新的局部变量(比如导入的List)。这就导致from typing import List导入的名称并没有被正确暴露给Test类内部的参数类型注解解析过程——类方法的参数类型注解在解析时,会尝试在类的作用域及外层可访问的命名空间中查找List,但此时List并没有被放入可被类定义访问的作用域内,最终抛出NameError: name 'List' is not defined。
可行修改的原理
下面逐个解释你提到的修改为什么能解决问题:
- 将
List替换为list:list是Python内置类型,存在于全局作用域中,类定义可以直接找到这个名称,不需要依赖导入的模块成员。 - 直接在主模块执行
exec(code):主模块的命名空间是全局命名空间,此时exec默认使用全局命名空间作为自己的全局和局部命名空间,导入的List会被放入全局命名空间,类定义可以正常访问。 - 传入
globals()作为locals参数给exec:显式指定exec使用全局命名空间作为局部命名空间,导入的List会被存入全局命名空间,类定义的注解解析过程能找到这个名称。 - 将类改为独立函数
boo:函数的参数类型注解解析规则和类不同,函数会优先在自己定义的外层作用域(也就是exec运行时的命名空间)查找名称,而函数的作用域对exec写入的名称兼容性更好,因此能找到导入的List。
内容的提问来源于stack exchange,提问作者Dano
相关产品推荐
相关产品推荐

