__annotations__ 不会为您提供父类的类型注释,因为它应该只包含在其自身类主体中定义的注释。有一个特定的函数可以返回一个类的所有注解,包括其父类的注解,称为typing.get_type_hints:
这通常与obj.__annotations__ 相同。 [...] 对于 C 类,返回一个字典,该字典是通过将所有 __annotations__ 与 C.__mro__ 以相反的顺序合并而成的。
在您的具体示例中使用它时要记住的一件事是,数据类使用大量黑魔法来构造类,如果 make_dataclass 定义中的某些字段没有类型化(提交为错误here):
import dataclasses as dc
from typing import Any, get_type_hints
@dc.dataclass
class B:
a: int
get_type_hints(B)
# returns {'a': <class 'int'>}
# fields=["w"] should be equivalent, but get_type_hints doesn't like it. Bug, maybe?
C = dc.make_dataclass("C", fields=[("w", Any)], bases=(B,))
typing.get_type_hints(C)
# returns {'a': <class 'int'>, 'w': typing.Any}
但正如 user2357112 指出的那样,最好建议您使用 dataclasses.fields 函数,该函数返回数据类装饰器根据数据类及其基础的注释构建的字段。这通常是您在分析数据类时想要使用的内容,它包含您需要的所有信息以及更多信息。
此外,它还可以与您最初使用的 make_dataclass 中字段的简写定义一起使用,并清除伪字段:
dc.fields(D)
# returns a tuple of
Field(name='a',type=<class 'int'>,default=<dataclasses._MISSING_TYPE object at 0x7f103d9985c0>,default_factory=<dataclasses._MISSING_TYPE object at 0x7f103d9985c0>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),_field_type=_FIELD)
# and
Field(name='w',type=typing.Any,default=<dataclasses._MISSING_TYPE object at 0x7f103d9985c0>,default_factory=<dataclasses._MISSING_TYPE object at 0x7f103d9985c0>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),_field_type=_FIELD)