dataclass 是 Python 3.7 引入的标准库特性(from dataclasses import dataclass),用于自动生成类的特殊方法(如 __init__、__repr__ 等),大幅减少样板代码。以下是详细教程。
目录
基本用法
1. 最简类定义
from dataclasses import dataclass
@dataclass
class Point:
x: int
y: int
# 自动生成 __init__, __repr__, __eq__ 等方法
p = Point(1, 2)
print(p) # 输出: Point(x=1, y=2)
2. 自动生成的方法
__init__: 初始化所有字段__repr__: 自动生成可读字符串表示__eq__: 基于字段值的比较__hash__: 若frozen=True则自动生成
字段定义与默认值
1. 指定默认值
@dataclass
class Product:
name: str
price: float = 0.0
in_stock: bool = True
p = Product("Laptop")
print(p) # 输出: Product(name='Laptop', price=0.0, in_stock=True)
2. 使用 field() 定制字段
from dataclasses import field, dataclass
@dataclass
class User:
name: str
hobbies: list = field(default_factory=list) # 避免可变默认值共享问题
id: str = field(default="", compare=False) # 不参与比较
u = User(name="Alice")
print(u) # 输出: User(name='Alice', hobbies=[], id='')
常用 field() 参数:
default: 固定默认值default_factory: 可调用对象生成默认值(如list,dict)init: 是否包含在__init__repr: 是否包含在__repr__compare: 是否参与比较
比较与排序
1. 启用排序功能
@dataclass(order=True)
class Student:
name: str
grade: int
s1 = Student("Alice", 85)
s2 = Student("Bob", 90)
print(s1 < s2) # 输出: True
2. 自定义比较逻辑
@dataclass(order=True)
class Student:
name: str
grade: int
def __post_init__(self):
# 可在此添加验证逻辑
if self.grade < 0:
raise ValueError("Grade cannot be negative")
不可变实例
@dataclass(frozen=True)
class ImmutablePoint:
x: int
y: int
p = ImmutablePoint(1, 2)
p.x = 3 # 抛出 FrozenInstanceError
继承与组合
1. 父类字段继承
@dataclass
class Base:
x: int = 1
@dataclass
class Sub(Base):
y: int
s = Sub(y=2)
print(s) # 输出: Sub(x=1, y=2)
2. 多继承注意
@dataclass
class A:
x: int
@dataclass
class B:
y: int
class C(A, B): # 需确保父类也是 dataclass
pass
常见用例
1. 数据模型类
@dataclass
class User:
id: int
name: str
email: str
2. 配置类
@dataclass
class Config:
host: str = "localhost"
port: int = 8080
debug: bool = False
3. DTO(数据传输对象)
@dataclass
class ProductDTO:
name: str
price: float
category: str = field(compare=False)
注意事项
1. 可变默认值陷阱
# 错误写法!所有实例共享同一列表
@dataclass
class BadClass:
data: list = [] # ❌
# 正确写法
@dataclass
class GoodClass:
data: list = field(default_factory=list) # ✅
2. __post_init__ 方法
用于初始化后验证或计算字段:
@dataclass
class Rectangle:
width: int
height: int
def __post_init__(self):
if self.width <= 0:
raise ValueError("Width must be positive")
3. 性能优化
- 避免在高频循环中使用
dataclass的__repr__和__eq__ - 对性能敏感场景可手动实现关键方法
4. 类型提示要求
必须显式声明字段类型(Python 3.7+):
@dataclass
class Example:
x = 10 # ❌ 缺少类型注解,不会被识别为字段
y: int = 20 # ✅ 正确
总结
dataclass 通过减少样板代码显著提升开发效率,适用于数据模型、配置管理等场景。核心优势:
- 自动生成常用方法
- 支持默认值和自定义逻辑
- 兼容不可变对象和继承
进一步学习:
- PEP 557 - Data Classes
dataclasses官方文档: https://docs.python.org/3/library/dataclasses.html