dataclass继承时__annotations__无法获取全部父类字段问题
为什么多重继承的dataclass子类__annotations__只包含第一个父类的字段?
核心原因
Python的__annotations__是类级别的独立属性,不会自动合并所有父类的注解:
- 每个类的
__annotations__仅存储自身显式定义的注解;当子类没有自己的注解时,会继承第一个父类的__annotations__(这是Python属性继承的默认逻辑),但不会主动合并后续父类的注解内容。 @dataclass装饰器虽然会正确识别并继承所有父类的dataclass字段(可以通过D3.__dataclass_fields__查看完整字段),但不会自动将这些父类的注解合并到子类的__annotations__中。
你可以先验证这一点:
print(D3.__dataclass_fields__.keys())
输出会是dict_keys(['d11', 'd12', 'd21', 'd22']),说明所有父类的字段其实都被dataclass正确处理了,只是__annotations__没显示而已。
解决办法:手动合并父类注解
如果需要让子类的__annotations__包含所有父类的字段注解,有两种常见方式:
1. 直接合并指定父类的注解
适合父类数量明确的场景:
from dataclasses import dataclass @dataclass class Data1: d11: str d12: float @dataclass class Data2: d21: str d22: float @dataclass class D3(Data1, Data2): __annotations__ = {**Data1.__annotations__, **Data2.__annotations__} print(D3.__annotations__)
运行后会输出完整的注解字典:
{'d11': <class 'str'>, 'd12': <class 'float'>, 'd21': <class 'str'>, 'd22': <class 'float'>}
2. 通过MRO自动合并所有父类注解
适合父类数量较多或动态变化的场景,利用Python的方法解析顺序(MRO)遍历所有父类并合并注解:
@dataclass class D3(Data1, Data2): __annotations__ = {} # 倒序遍历MRO,确保子类自身注解(如果有的话)优先级最高 for cls in reversed(__mro__): __annotations__.update(getattr(cls, '__annotations__', {}))
这样就能让子类的__annotations__包含所有父类的字段注解了。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

