Python 3.x 内置装饰器 (4) - @dataclass

@dataclass 是Python 3.7 引入的一个装饰器,用来简化创建数据类(主要存储数据的类)的过程。它会自动为类生成一些常用的方法,比如:

init: 对象的初始化

repr: 定义类的官方字符串表示。

eq: 定义两个对象是否相等

lt: 定义两个对象的比较运算符

__post_init__:在__init__后执行,进行额外的初始化。

等,大大减少了代码的冗余。举一个简单的例子:

复制代码
from dataclasses import dataclass

@dataclass
class Point:
    x: int
    y: 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__ 方法来初始化 xy

  • 自动生成了 __repr__ 方法,使得 print(p1) 输出一个易于理解的字符串。

  • 自动生成了 __eq__ 方法,使得你可以直接用 == 来比较两个对象。

使用 @dateclass 可以给字段指定默认值,或者使用 field 来为字段设置更复杂的默认值,例如:

复制代码
from dataclasses import dataclass, field

@dataclass
class Rectangle:
    width: int
    height: int
    color: 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: str
    age: int
    city: 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: str
    model: str
    features: 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: int
    y: int

p1 = Point(1, 2)
p2 = Point(1, 2)

print(p1)  # Output: <__main__.Point object at ...> (没有 repr 方法)
print(p1 == p2)  # Output: False (没有 eq 方法)

总之,@dataclass 是一个特别强大,用法又特别灵活的类,小伙伴们掌握了多少。

相关推荐
飞Link4 分钟前
告别复杂调参:Prophet 加法模型深度解析与实战
开发语言·python·数据挖掘
测试人社区—66796 分钟前
当代码面临道德选择:VR如何为AI伦理决策注入“人性压力”
网络·人工智能·python·microsoft·vr·azure
独行soc16 分钟前
2026年渗透测试面试题总结-36(题目+回答)
网络·python·安全·web安全·网络安全·渗透测试·安全狮
zh_xuan22 分钟前
测试go语言函数和结构体
开发语言·golang
witAI24 分钟前
**Kimi小说灵感2025推荐,从零到一的创意激发指南**
人工智能·python
小龙报32 分钟前
【算法通关指南:算法基础篇】二分算法: 1.A-B 数对 2.烦恼的高考志愿
c语言·开发语言·数据结构·c++·vscode·算法·二分
yong999035 分钟前
NNDA、PDA、JPDA、IMM数据关联算法MATLAB实现
开发语言·算法·matlab
飞Link40 分钟前
深度解析:基于专家的监管方法(Expert-Based Supervision)在复杂系统中的应用
python·数据挖掘·回归
Shining059643 分钟前
Triton & 九齿系列《Triton 练气术》
开发语言·人工智能·python·学习·其他·infinitensor
天远Date Lab1 小时前
天远企业司法认证API实战:Python构建企业级供应链合规审查防火墙
大数据·开发语言·网络·python