@dataclass
是 Python 3.7 引入的一个装饰器,用于简化数据类的定义。它可以自动为类生成常用的特殊方法,例如 __init__
、__repr__
、__eq__
等,从而减少样板代码的编写,提高代码的可读性。
下面通过几个示例来说明如何使用 @dataclass
。
from dataclasses import dataclass
@dataclass
class Point:
x: float
y: float
# 创建 Point 对象
p = Point(1.5, 2.5)
print(p) # 输出:Point(x=1.5, y=2.5)
说明:
@dataclass
自动为 Point
类生成了 __init__
和 __repr__
方法。Point(1.5, 2.5)
创建对象,无需手动定义 __init__
方法。print(p)
时,自动调用生成的 __repr__
方法,方便调试和输出。from dataclasses import dataclass
@dataclass
class Person:
name: str
age: int = 30 # 默认年龄为30
# 创建 Person 对象
person1 = Person("Alice", 25)
person2 = Person("Bob")
print(person1) # 输出:Person(name='Alice', age=25)
print(person2) # 输出:Person(name='Bob', age=30)
说明:
age
参数,age
将默认设置为 30。from dataclasses import dataclass
@dataclass
class Rectangle:
width: float
height: float
rect1 = Rectangle(10, 20)
rect2 = Rectangle(10, 20)
rect3 = Rectangle(15, 25)
print(rect1 == rect2) # 输出:True
print(rect1 == rect3) # 输出:False
说明:
@dataclass
自动生成了 __eq__
方法,可以直接比较对象的内容是否相等。from dataclasses import dataclass
@dataclass
class Circle:
radius: float
def area(self):
from math import pi
return pi * self.radius ** 2
circle = Circle(3)
print(f"圆的面积是:{circle.area()}") # 输出:圆的面积是:28.274333882308138
说明:
area
方法计算圆的面积。@dataclass
提供了 field
函数,可以设置字段的更多选项,例如:是否参与比较、在 __repr__
中显示等。
from dataclasses import dataclass, field
@dataclass
class Book:
title: str
author: str
_price: float = field(repr=False) # 不在 __repr__ 中显示
isbn: str = field(compare=False) # 不参与比较
book1 = Book("Python Programming", "John Doe", 39.99, "1234567890")
book2 = Book("Python Programming", "John Doe", 39.99, "0987654321")
print(book1) # 输出:Book(title='Python Programming', author='John Doe')
print(book1 == book2) # 输出:True,因为 isbn 不参与比较
说明:
field(repr=False)
:设置 _price
字段在 __repr__
中不显示。field(compare=False)
:设置 isbn
字段在比较时被忽略。如果希望数据类的实例是不可变的(即实例化后不能修改属性),可以使用参数 frozen=True
。
from dataclasses import dataclass
@dataclass(frozen=True)
class Coordinate:
x: float
y: float
point = Coordinate(5, 10)
print(point) # 输出:Coordinate(x=5, y=10)
# 尝试修改属性会引发错误
# point.x = 15 # AttributeError: cannot assign to field 'x'
说明:
frozen=True
,数据类变为不可变类型。AttributeError
。数据类可以支持继承,子类会继承父类的字段。
from dataclasses import dataclass
@dataclass
class Animal:
name: str
@dataclass
class Dog(Animal):
breed: str
dog = Dog("Buddy", "Golden Retriever")
print(dog) # 输出:Dog(name='Buddy', breed='Golden Retriever')
说明:
Dog
类继承自 Animal
,拥有 name
和 breed
两个字段。__post_init__
进行初始化检查如果需要在自动生成的 __init__
方法后添加额外的初始化逻辑,可以定义 __post_init__
方法。
from dataclasses import dataclass
@dataclass
class Student:
name: str
grade: float
def __post_init__(self):
if self.grade < 0 or self.grade > 100:
raise ValueError("成绩必须在0到100之间")
student = Student("Alice", 95)
# student_with_error = Student("Bob", 105) # ValueError: 成绩必须在0到100之间
说明:
__post_init__
方法在自动生成的 __init__
方法执行后被调用。__post_init__
中添加参数验证或其他初始化逻辑。总结
@dataclass
装饰器的作用是简化数据类的定义,自动生成常用方法,使代码更简洁、可读性更高。它特别适用于需要存储大量数据但不需要复杂方法的类。在实际编程中,@dataclass
常用于: