DataClasses - Class Attribute#

有的时候你需要给你的类一个常数的属性. 这个属性可以通过 self.attr_name 来访问. 虽然说你可以直接在 Class 下面定义属性, 但是很多 ORM 框架 (例如 dataclasses, attrs, sqlalchemy) 会将其视为一个实例的属性定义, 而不是类的属性定义. 并且你再继承类的时候, 这个属性如果是 mutable 的话, 很容易会犯错误.

正确的做法是, 即使这个属性是一个 class attribute, 你也应该创建一个 @classmethod 来访问它. 这样可以避免很多错误, 并且显式滴在父类中定义 raise NotImplementedError 能提醒你在子类中实现这个方法.

[15]:
import dataclasses
from rich import print as rprint

@dataclasses.dataclass
class FirstModel:
    attr1: int = dataclasses.field()

    @classmethod
    def class_attr(cls) -> str:
        return"this is first model"


@dataclasses.dataclass
class SecondModel(FirstModel):
    attr1: int = dataclasses.field(default=None)

    @classmethod
    def class_attr(cls) -> str:
        return"this is second model"
[16]:
second_model = SecondModel(attr1=1)
rprint(second_model)
SecondModel(attr1=1)
[17]:
rprint(dataclasses.asdict(second_model))
{'attr1': 1}
[18]:
second_model.class_attr()
[18]:
'this is second model'
[19]:
rprint(dataclasses.fields(SecondModel))
(
    Field(name='attr1',type=<class 'int'>,default=None,default_factory=<dataclasses._MISSING_TYPE object at 
0x104309bb0>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),_field_type=_FIELD),
)
[ ]: