我正在学习dataclass,我很难理解为什么__annotations__没有给出父类中的字段。见下面的例子:
import dataclasses as dc
@dc.dataclass
class B:
a: int
B.__annotations__
# returns {'a': int}
C = dc.make_dataclass("c", fields=["w"], bases=(B,))
C.__annotations__
# returns {'w': 'typing.Any'} (without a)发布于 2019-08-22 12:28:11
__annotations__不为您提供父类的类型注释,因为它应该只保存自身类主体中定义的注释。有一个特定的函数返回一个类的所有注释,包括它的父类的注释,称为typing.get_type_hints。
这通常与
obj.__annotations__相同。..。对于一个类C,返回一个字典,该字典由沿着__annotations__沿C.__mro__按反向顺序合并而构造。
在您的具体示例中使用它时要记住的一件事是,数据类使用大量黑魔法来构造类,如果在make_dataclass定义中某些字段是非类型化的(作为bug 这里归档),它将中断查找所有类型提示:
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)https://stackoverflow.com/questions/57601705
复制相似问题