Python Dataclass报错:作用域内的FooType未被解释器识别
问题原因及解决思路
问题原因
Python代码是从上到下顺序执行解析的。当定义Foo类并给type字段标注FooType类型时,FooType枚举类还没被定义——它在Foo类之后才出现,此时解释器找不到这个名称,直接抛出NameError。
类的作用域不会自动“回溯”引用后续定义的对象,哪怕在同一个文件里,只要代码执行到注解位置时目标类还未创建,就会触发这个错误。
解决思路
有三种常用的修复方式:
1. 调整定义顺序
把FooType枚举类移到Foo数据类前面,这样解析Foo时FooType已经存在:
from dataclasses import dataclass from enum import Enum class FooType(Enum): BAR = 0, BAZ = 1 @dataclass class Foo: type: FooType if __name__ == '__main__': foo = Foo(type=FooType.BAR)
2. 使用字符串类型注解(向前引用)
Python支持用字符串包裹尚未定义的类型名称,解释器会在后续代码执行时识别这个名称:
from dataclasses import dataclass from enum import Enum @dataclass class Foo: type: 'FooType' # 用字符串包裹类名实现向前引用 class FooType(Enum): BAR = 0, BAZ = 1 if __name__ == '__main__': foo = Foo(type=FooType.BAR)
如果使用Python 3.7及以上版本,还可以通过导入__future__模块,让所有类型注解默认以字符串形式存储,无需手动加引号:
from __future__ import annotations from dataclasses import dataclass from enum import Enum @dataclass class Foo: type: FooType # 无需引号,自动延迟解析 class FooType(Enum): BAR = 0, BAZ = 1 if __name__ == '__main__': foo = Foo(type=FooType.BAR)
3. 延迟赋值类型注解(不推荐)
先定义Foo类并给type字段临时占位,后续再修改类型注解,这种方式不够简洁,一般不建议使用:
from dataclasses import dataclass from enum import Enum @dataclass class Foo: type: object # 临时用object占位 class FooType(Enum): BAR = 0, BAZ = 1 Foo.__annotations__['type'] = FooType # 后续修改类型注解 if __name__ == '__main__': foo = Foo(type=FooType.BAR)
内容的提问来源于stack exchange,提问作者user2752148
相关产品推荐
相关产品推荐

