@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 是一个特别强大,用法又特别灵活的类,小伙伴们掌握了多少。