我想得到所有的注释,包括属性注释。我得到的只是为常规注释设置的注释:
from dataclasses import dataclass
@dataclass
class Test:
first: int = 1
@property
def second(self) -> int:
return 5
t = Test()
print(t.__annotations__)
# prints: {'first': <class 'int'>}有没有办法让“第二”成为__annotations__的一部分?甚至可能强迫它进入__anotations__。
发布于 2021-04-02 18:15:19
使用__annotations__获取如何将数据块转换为json的信息似乎是个坏主意。它要么阻止您使用诸如InitVar或ClassVar之类的瞬态属性,要么导致不一致和错误的行为(如果您确实使用了它们)。您应该使用__dataclass_fields__代替。
尽管如此,有时您的用例非常简单,可以执行,或者您被一个无法轻松改进的第三方包锁定在其中,所以这里有一种方法可以将dataclass的__annotations__扩展到其属性上的那些包中:
class Test:
var: int
@property
def x(self) -> int:
return self.var + 2
def __post_init__(self):
cls = type(self)
properties = [(x, getattr(cls, x)) for x in dir(cls) if type(getattr(cls, x)) == property]
for name, property_ in properties:
cls.__annotations__[name] = property_.fget.__annotations__["return"]创建Test的实例现在将包含属性,就像它是一个常规类型的属性一样:
>>> Test(1).__annotations__
{'var': <class 'int'>, 'x': <class 'int'>}顺便提一下,__post_init__代码是在每个实例的初始化过程中执行的,尽管严格地说,它只需要在类生成时运行一次,因为__annotations__是在类级别上定义的。因为它是幂等的,所以它不会破坏任何东西,但是这里是一个更令人困惑但可以说更简洁的应用程序,同样的代码也适用于普通类。
https://stackoverflow.com/questions/66902712
复制相似问题