Python dataclass

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(数据传输对象)等场景。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值