如何为Python dataclass添加非字段的类型提示属性?
在Python Dataclass中排除派生属性并保留类型提示
下面几种方案可以解决你的问题,既能让派生属性不被识别为dataclass字段,又能保留类型提示:
方案1:类定义后手动清理dataclass标记
直接在类里写派生属性的类型提示,然后在类定义完成后,把这些属性从dataclass的内部标记中移除:
from dataclasses import dataclass, fields, KW_ONLY @dataclass class MyDataClass: field0: int field1: int _: KW_ONLY fieldN: int # 先写好类型提示 attr0: int attr1: int def __post_init__(self): # 初始化派生属性 self.attr0 = self.field0 + self.field1 self.attr1 = self.fieldN * 2 # 从dataclass的字段列表和注解中移除这些属性 del MyDataClass.__annotations__['attr0'] del MyDataClass.__annotations__['attr1'] del MyDataClass.__dataclass_fields__['attr0'] del MyDataClass.__dataclass_fields__['attr1']
这样处理后,fields(MyDataClass)只会返回你真正需要的字段,而类型检查器依然能识别attr0和attr1的类型。
方案2:动态创建dataclass+基类声明类型
先定义一个包含派生属性类型提示的基类,再用make_dataclass动态生成dataclass,只传入需要作为字段的属性:
from dataclasses import dataclass, KW_ONLY, make_dataclass # 基类专门声明派生属性的类型提示 class MyDataClassBase: attr0: int attr1: int def __post_init__(self): self.attr0 = self.field0 + self.field1 self.attr1 = self.fieldN * 2 # 动态生成dataclass,只包含核心字段 MyDataClass = make_dataclass( 'MyDataClass', [ ('field0', int), ('field1', int), ('_', KW_ONLY), ('fieldN', int), ], bases=(MyDataClassBase,), )
这种方式更清晰,dataclass生成时只会处理你指定的字段,基类的属性不会被当作dataclass字段,但类型提示完全有效。
方案3:用@property封装私有属性
如果可以接受用属性访问器,也可以把派生属性封装成私有变量,再用@property暴露:
from dataclasses import dataclass, KW_ONLY @dataclass class MyDataClass: field0: int field1: int _: KW_ONLY fieldN: int def __post_init__(self): # 给私有属性赋值并标注类型 self._attr0 = self.field0 + self.field1 # type: int self._attr1 = self.fieldN * 2 # type: int @property def attr0(self) -> int: return self._attr0 @property def attr1(self) -> int: return self._attr1
这种写法下,_attr0和_attr1不会被dataclass识别为字段,同时类型检查器能通过注释和@property的返回类型识别属性类型。
内容的提问来源于stack exchange,提问作者Hyperplane
相关产品推荐
相关产品推荐

