Python 提供很多语法糖,用起来非常方便。@dataclass 就是其中之一。
顾名思义,用它修饰的类是一个数据类,有点类似于 C++里的 plain struct ,会自动给类添加初始化__init__
、__eq__
等函数。比如类:
from dataclasses import dataclass
@dataclass
class InventoryItem:
"""Class for keeping track of an item in inventory."""
name: str
unit_price: float
quantity_on_hand: int = 0
def total_cost(self) -> float:
return self.unit_price * self.quantity_on_hand
会自动添加下面的__init__
初始化函数:
def __init__(self, name: str, unit_price: float, quantity_on_hand: int=0):
self.name = name
self.unit_price = unit_price
self.quantity_on_hand = quantity_on_hand
如果在普通的初始化外还想自定义,可以自定义__post__init__
函数,配合设置field(init=False)
:
from dataclasses import dataclass, field
@dataclass
class C:
a: float
b: float
c: float = field(init=False)
def __post_init__(self):
self.c = self.a + self.b
类C
事实上自动添加了下面的初始化函数:
def __init__(self, a, b):
self.a = a
self.b = b
self.__post__init()
还有一个有意思的东西是初始化。类成员直接用[]
或者{}
初始化,类似于函数的默认参数问题,将导致不同类共享同一个成员( Python 的一个大 bug !)。
from dataclasses import dataclass, field
@dataclass
class D:
x: [] # 会引发问题,不同类共享同一个[]
y: {} # 会引发问题,不同类共享同一个{}
xx: field(default_factory=list) # ok
yy: field(default_factory=dict) #ok
对于 dataclass ,dataclasses.as_tuple
可以将类的成员依次取出,以 tuple 的方式返回。
Q. E. D.