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 是一个特别强大,用法又特别灵活的类,小伙伴们掌握了多少。

相关推荐
B站计算机毕业设计之家19 小时前
智慧交通项目:Python+PySide6 车辆检测系统 YOLOv8+OpenCV 自定义视频 自定义检测区域 (源码+文档)✅
大数据·python·opencv·yolo·智慧交通·交通·车流量
java1234_小锋19 小时前
TensorFlow2 Python深度学习 - 深度学习概述
python·深度学习·tensorflow·tensorflow2·python深度学习
一念&20 小时前
每日一个C语言知识:C 数据类型
c语言·开发语言
迈火20 小时前
PuLID_ComfyUI:ComfyUI中的图像生成强化插件
开发语言·人工智能·python·深度学习·计算机视觉·stable diffusion·语音识别
wzg201620 小时前
vscode 配置使用pyqt5
开发语言·数据库·qt
板鸭〈小号〉1 天前
Socket网络编程(1)——Echo Server
开发语言·网络·php
明天会有多晴朗1 天前
C语言入门教程(第1讲):最通俗的C语言常见概念详解与实战讲解
c语言·开发语言·c++
爱上妖精的尾巴1 天前
5-20 WPS JS宏 every与some数组的[与或]迭代(数组的逻辑判断)
开发语言·前端·javascript·wps·js宏·jsa
gopher95111 天前
Go 语言的 panic 和 recover
开发语言·golang
浔川python社1 天前
《网络爬虫技术规范与应用指南系列》(xc—5)完
爬虫·python