You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 21:53:16