python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python @dataclass装饰器

Python @dataclass装饰器举例详解

作者:添财小哥

装饰器是Python中的一种高级功能,它允许你动态地修改函数或类的行为,这篇文章主要介绍了Python @dataclass装饰器的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

1. 用途和主要功能

@dataclass 是 Python 3.7 引入的一个装饰器(位于标准库 dataclasses 模块中),用于简化“纯数据”类的定义。它自动为类生成常用的特殊方法(如 initrepreq 等),避免手动编写冗余模板代码。这样定义的数据类在代码量和可读性上都有显著优势,如便于维护、减少错误。使用 @dataclass 后,我们“可以直接创建和操作对象,而无需手动编写这些基础方法”。总体而言,@dataclass 提高了代码的一致性和可维护性,尤其适用于以存储数据为主的场景。

优势总结:

2.基本用法

基本用法示例如下:只需从 dataclasses 模块导入装饰器,使用 @dataclass 标注类,类体中定义带类型注解的字段即可。示例代码:

from dataclasses import dataclass

@dataclass
class InventoryItem:
    """库存项目的数据类示例"""
    name: str
    unit_price: float
    quantity_on_hand: int = 0

    def total_cost(self) -> float:
        return self.unit_price * self.quantity_on_hand

如官方文档所示,上例自动生成了类似下面的 init() 方法

def __init__(self, name: str, unit_price: float, quantity_on_hand: int = 0):
    self.name = name
    self.unit_price = unit_price
    self.quantity_on_hand = quantity_on_hand

此外,默认情况下还会生成符合字段顺序的 repreq 方法,使得打印实例和比较相等都更方便。例如:

item = InventoryItem("widget", 3.0, 10)
print(item)            # 输出: InventoryItem(name='widget', unit_price=3.0, quantity_on_hand=10)
item2 = InventoryItem("widget", 3.0, 10)
assert item == item2   # 基于字段值进行比较

以上示例中,InventoryItem 类依然可以定义自定义方法(如 total_cost),@dataclass 只负责处理字段相关的方法生成,不会影响其它方法定义

3. 参数详解

@dataclass 装饰器支持多种可选参数,用于控制生成方法的行为及类的特性。常见参数及其含义如下(括号内为默认值):

以上参数均可通过 @dataclass(…) 形式传入,或直接 @dataclass 使用默认值。以官方文档为例,以下三种写法是等价的:

@dataclass
class C: ...
@dataclass()
class C: ...
@dataclass(init=True, repr=True, eq=True, order=False, unsafe_hash=False, 
           frozen=False, match_args=True, kw_only=False, slots=False)
class C: ...

4. 底层设计逻辑

@dataclass 在类创建时动态修改类定义,以生成所需的方法和属性。其核心实现机制包括:

@dataclass
class Base:
    x: Any = 15.0
    y: int = 0

@dataclass
class C(Base):
    z: int = 10
    x: int = 15

最终 C 的字段顺序为 (‘x’, ‘y’, ‘z’),其中 x 的类型为 int(覆盖了 Base 的定义)。

5. 使用场景

dataclass 适用于定义主要用于存储数据且方法较少的类,常见场景包括:

6. 高级用法与扩展

from dataclasses import dataclass, field

@dataclass
class C:
    # 默认工厂:为每个实例生成一个新列表
    items: list = field(default_factory=list, repr=False, metadata={"info": "缓存列表"})

如上所示,default_factory=list 确保每个实例的 items 字段初始为一个独立的空列表(避免多个实例共享同一个列表)。repr=False 则让 items 字段不出现在自动生成的 repr 中。metadata 可以附加任意只读元数据(以供框架或工具使用),Dataclasses 本身不使用它。

from dataclasses import dataclass, field, InitVar

@dataclass
class C:
    x: int
    data_source: InitVar[str] = None

    def __post_init__(self, data_source):
        if self.x is None and data_source:
            self.x = load_default_from(data_source)

7. 注意事项与局限性

总结 

到此这篇关于Python @dataclass装饰器的文章就介绍到这了,更多相关Python @dataclass装饰器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文