@dataclass 是Python 3.7 引入的一個裝飾器,用來簡化創建數據類(主要存儲數據的類)的過程。它會自動為類生成一些常用的方法,比如:
__init__: 對象的初始化
__repr__: 定義類的官方字符串表示。
__eq__: 定義兩個對象是否相等
__lt__: 定義兩個對象的比較運算符
__post_init__:在__init__后執行,進行額外的初始化。
等,大大減少了代碼的冗余。舉一個簡單的例子:
from dataclasses import dataclass@dataclass
class Point:x: inty: int# 創建對象時,自動生成 __init__ 方法
p1 = Point(1, 2)
p2 = Point(1, 2)print(p1) # Output: Point(x=1, y=2)
print(p1 == p2) # Output: True
在這個例子中,
-
Point
類自動擁有了__init__
方法來初始化x
和y
。 -
自動生成了
__repr__
方法,使得print(p1)
輸出一個易于理解的字符串。 -
自動生成了
__eq__
方法,使得你可以直接用==
來比較兩個對象。
使用 @dateclass?可以給字段指定默認值,或者使用 field
來為字段設置更復雜的默認值,例如:
from dataclasses import dataclass, field@dataclass
class Rectangle:width: intheight: intcolor: str = "blue" # 默認值tags: list = field(default_factory=list) # 使用 default_factory 為可變類型字段指定默認值r1 = Rectangle(10, 20)
print(r1.color) # Output: blue
print(r1.tags) # Output: []
這里的 field()
可以讓你控制如何處理每個字段,例如設置默認值、指定字段是否可修改等。
from dataclasses import dataclass, field@dataclass
class Person:name: strage: intcity: str = field(default="Unknown", repr=False) # 不在 __repr__ 輸出中顯示person = Person("Alice", 30)
print(person) # Output: Person(name='Alice', age=30)
對于可變類型(如 list、dict 等),如果你在類中直接給它們賦默認值,你可能會遇到問題,因為默認值會被共享到所有實例中。為了解決這個問題,應該使用 field(default_factory=...) 來為每個實例提供新的默認值。
from dataclasses import dataclass, field@dataclass
class Car:make: strmodel: strfeatures: list = field(default_factory=list) # 每個實例都有自己的 features 列表car1 = Car("Toyota", "Corolla")
car2 = Car("Honda", "Civic")car1.features.append("Air Conditioning")
print(car1.features) # Output: ['Air Conditioning']
print(car2.features) # Output: []
最后,你可以通過設置 dataclass
參數來禁用自動生成某些方法。例如,如果你不想生成 __repr__
或 __eq__
方法,可以這樣做:
from dataclasses import dataclass@dataclass(repr=False, eq=False)
class Point:x: inty: intp1 = Point(1, 2)
p2 = Point(1, 2)print(p1) # Output: <__main__.Point object at ...> (沒有 repr 方法)
print(p1 == p2) # Output: False (沒有 eq 方法)
總之,@dataclass 是一個特別強大,用法又特別靈活的類,小伙伴們掌握了多少。