Python使用make_dataclass创建递归数据类如何解决NameError报错
问题原因
动态使用make_dataclass创建类时,只会返回类对象,不会自动将类注册到当前作用域的全局命名空间中。你使用了字符串形式的前向引用"node"作为类型注解,typing.get_type_hints解析注解时会到命名空间中查找对应名称的类,找不到就会抛出NameError。
可用解决方案
方案1:手动传入解析用命名空间(无侵入,推荐)
get_type_hints支持传入globalns参数自定义解析注解用的命名空间,不需要修改全局环境:
import dataclasses import typing as t node_type = dataclasses.make_dataclass( "node", [("child", t.Optional["node"], dataclasses.field(default=None))] ) print(t.get_type_hints(node_type, globalns={"node": node_type}))
方案2:将类注册到全局命名空间
直接把创建的类放到当前模块的全局命名空间中,适配所有需要解析注解的场景:
import dataclasses import typing as t node_type = dataclasses.make_dataclass( "node", [("child", t.Optional["node"], dataclasses.field(default=None))] ) globals()["node"] = node_type print(t.get_type_hints(node_type))
方案3:使用Self类型(需要额外依赖)
Python 3.11及以上版本标准库typing提供了Self类型,3.9版本可以安装typing-extensions包使用该类型,不需要写字符串前向引用:
- 先安装依赖:
pip install typing-extensions - 代码示例:
import dataclasses import typing as t from typing_extensions import Self node_type = dataclasses.make_dataclass( "node", [("child", t.Optional[Self], dataclasses.field(default=None))] ) print(t.get_type_hints(node_type))
以上三种方案运行后都会输出正确的类型注解结果:
{'child': typing.Optional[__main__.node]}
内容的提问来源于stack exchange,提问作者Luke Murray
相关产品推荐
相关产品推荐

