dataclass 是 Python 3.7+ 引入的一个装饰器,用于自动生成常见特殊方法(如 __init__、__repr__ 等),大大简化了数据类的编写。
基本使用
from dataclasses import dataclass
# 基本定义
@dataclass
class Person:
name: str
age: int
email: str = "" # 带默认值
# 使用
person = Person("Alice", 30)
print(person) # Person(name='Alice', age=30, email='')
主要特性
1. 字段类型和默认值
from dataclasses import dataclass, field
from typing import List, Optional
@dataclass
class Student:
# 必需字段
name: str
student_id: int
# 可选字段
age: Optional[int] = None
# 使用 field 设置默认值
courses: List[str] = field(default_factory=list)
# 排除在 __repr__ 之外
_private: str = field(default="secret", repr=False)
# 使用
student = Student("Bob", 12345)
student.courses.append("Math") # 列表被正确初始化
print(student) # Student(name='Bob', student_id=12345, age=None)
2. 字段配置选项
from dataclasses import dataclass, field
@dataclass
class Product:
name: str
price: float
quantity: int = field(default=0)
# 不在比较中使用
metadata: dict = field(default_factory=dict, compare=False)
# 哈希时忽略
cached_total: float = field(default=0.0, hash=False)
3. 特殊选项
from dataclasses import dataclass
# frozen=True: 创建不可变对象
@dataclass(frozen=True)
class ImmutablePoint:
x: int
y: int
# order=True: 自动生成比较方法
@dataclass(order=True)
class Person:
name: str
age: int
# 使用
point = ImmutablePoint(10, 20)
# point.x = 30 # 错误:frozen 对象不可修改
# 排序
people = [Person("Alice", 30), Person("Bob", 25)]
people.sort() # 按 age 排序
print(people) # [Person(name='Bob', age=25), Person(name='Alice', age=30)]
高级用法
1. 后初始化处理
from dataclasses import dataclass
@dataclass
class Rectangle:
width: float
height: float
area: float = 0.0
def __post_init__(self):
"""初始化后自动计算面积"""
self.area = self.width * self.height
rect = Rectangle(5, 3)
print(rect) # Rectangle(width=5, height=3, area=15)
2. 继承
@dataclass
class Person:
name: str
age: int
@dataclass
class Employee(Person):
employee_id: str
department: str = "General"
emp = Employee("Alice", 30, "E123", "Engineering")
print(emp) # Employee(name='Alice', age=30, employee_id='E123', department='Engineering')
3. 可变与不可变
@dataclass
class MutablePerson:
name: str
age: int
@dataclass(frozen=True)
class ImmutablePerson:
name: str
age: int
# 可变
mutable = MutablePerson("Alice", 30)
mutable.age = 31 # 允许修改
# 不可变
immutable = ImmutablePerson("Bob", 25)
# immutable.age = 26 # 错误:frozen 对象
实用技巧
1. 使用 field() 的高级配置
from dataclasses import dataclass, field
from typing import Any
@dataclass
class Config:
# 设置默认值并跳过比较
version: str = field(default="1.0", compare=False)
# 动态创建默认值
data: list = field(default_factory=lambda: ["default", "values"])
# 自定义 metadata
sensitive: str = field(
default="",
metadata={"secret": True, "encrypted": False}
)
# 初始化后不包含在 repr 中
cache: Any = field(default=None, repr=False)
2. 转换为字典或元组
from dataclasses import dataclass, asdict, astuple
@dataclass
class Point:
x: int
y: int
z: int = 0
p = Point(1, 2, 3)
# 转换为字典
d = asdict(p)
print(d) # {'x': 1, 'y': 2, 'z': 3}
# 转换为元组
t = astuple(p)
print(t) # (1, 2, 3)
3. 替换对象(创建副本)
from dataclasses import dataclass, replace
@dataclass
class Person:
name: str
age: int
city: str = "Unknown"
p1 = Person("Alice", 30, "New York")
# 创建修改后的副本
p2 = replace(p1, age=31, city="Boston")
print(p2) # Person(name='Alice', age=31, city='Boston')
与其他库的集成
JSON 序列化
import json
from dataclasses import dataclass, asdict
@dataclass
class User:
name: str
email: str
user = User("Alice", "alice@example.com")
# 序列化
json_str = json.dumps(asdict(user))
print(json_str) # {"name": "Alice", "email": "alice@example.com"}
# 反序列化
data = json.loads(json_str)
user2 = User(**data)
与类型提示配合
from dataclasses import dataclass
from typing import List, Dict, Optional, Union
@dataclass
class ComplexData:
id: int
name: str
tags: List[str] = field(default_factory=list)
metadata: Dict[str, Union[str, int]] = field(default_factory=dict)
optional_field: Optional[str] = None
总结
-
简化代码:自动生成
__init__、__repr__、__eq__等方法 -
类型安全:支持类型提示
-
灵活配置:通过参数控制可变性、比较、哈希等行为
-
性能良好:比手动编写这些方法更高效
-
易于维护:减少样板代码,提高可读性
dataclass 非常适合用于数据容器、配置对象、DTO(数据传输对象)等场景。
2627

被折叠的 条评论
为什么被折叠?



