python3.7引入了装饰器@dataclass,用于简化创建类并定义数据模型的过程。使用 @dataclass 装饰器可以自动添加一些通用的特殊方法,如 init、repr 等,从而减少代码量。
官方教程:https://peps.python.org/pep-0557/
下面,从官网的例子开始讲解。首先定义一个特殊的类InventoryItem:
class InventoryItem0:
name: str
unit_price: float
quantity_on_hand: int = 0
item0 = InventoryItem0()
上面这个类InventoryItem0,看上去好像定义了name、unit_price、quantity_on_hand属性,实际上这个类什么
也做不了。我们知道,类中的方法是通过函数来定义的,而属性是通过方法来定义的,因此上面这个
类没有方法,无法定义相应的属性,也就无法产生真正意义上的实例。如果传入一个方法,再在方法
下定义属性,就符合类定义的逻辑。如:
class InventoryItem1:
def __init__(self, name, unit_price, quantity_on_hand):
self.name: str = name
self.unit_price: float= unit_price
self.quantity_on_hand: int= quantity_on_hand
item1 = InventoryItem1('jack', 3.5, 8)
print(item1.name, item1.unit_price, item1.quantity_on_hand)
我们定义了一个类InventoryItem,在这个类下定义了一个方法,即初始化方法__init__(双下划线),然后在这个方法下定义三个属性,name,unit_price,quantity_on_hand,这样就能自然地实现很多功能。注:在每个属性后’: str’,是python3.5引入的类型提示符,这个也非常有用。然后,我们还可以在定义一个方法,以及属性。除了定义初始化方法,我们还可以定义其他方法,如:
class InventoryItem2:
def __init__(self, name, unit_price, quantity_on_hand):
self.name: str = name
self.unit_price: float= unit_price
self.quantity_on_hand: int= quantity_on_hand
def sec_method(self, another_pro: float):
self.another_pro = another_pro+self.unit_price
return self.another_pro
item2 = InventoryItem2('jack2', 4.5, 9)
print(item2.name, item2.unit_price, item2.quantity_on_hand)
item2.sec_method(4.3)#方法调用
InvertoryItem2就是我们平时所写的类。python的格言是追求极致简洁和优雅,工程师们还是认为上面的初始化方法还是不够简洁和优雅,能否再简洁一些和优雅一点,于是装饰器@dataclass就出现了,一种数据类装饰器,这个方法能自动添加如 init、repr 等,从而减少代码量。如改写Inventory1有:
from dataclasses import dataclass
@dataclass()
class InventoryItem1:
name: str
unit_price: float
quantity_on_hand: int
item1 = InventoryItem1('jack', 3.5, 8)
print(item1.name, item1.unit_price, item1.quantity_on_hand)
print(item1)#返回一个实例化的类
这样是不是极致简洁和优雅。改写Inventory2,有:
@dataclass()
class InventoryItem2:
name: str
unit_price: float
quantity_on_hand: int
def sec_method(self, another_pro: float):
self.another_pro = another_pro+self.unit_price
return self.another_pro
item2 = InventoryItem2('jack2', 4.5, 9)
print(item2.name, item2.unit_price, item2.quantity_on_hand)
同样可以添加方法sec_method,但要注意对齐方法。官网显示(https://peps.python.org/pep-0557/) @dataclass可以自动添加8种方法。这里只讲解了常用情况,@dataclass()还有其他作用。详见官网。