@dataclass装饰器简单用法

dataclass是从Python3.7版本开始,作为标准库中的模块被引入,提供便捷的数据类创建和管理方式。

引言

Dataclass是Dataclasses模块的一种装饰器,当使用@dataclass装饰器时,会自动生成一些特殊的方法,包括:

  • __init__: 根据类属性初始化实例。

  • __repr__: 用于打印或调试时显示实例信息。

  • __eq__: 用于比较两个实例是否相等。

  • 还可以根据需要生成 __lt____le____gt____ge__ 等方法(通过 order=True 参数)。

用法

不使用dataclass

class data:
    def __init__(self, x,y):
        self.x = x
        self.y = y
    def __repr__(self):
        return f'data(x={self.x},y={self.y})'
    
d = data(1,2)
print(d)

输出

data(x=1,y=2)
from dataclasses import dataclass
 
@dataclass
class data:
    x: int
    y: int
 
# 使用数据类
d = data(1, 2)
print(d) 

输出

data(x=1, y=2)

 可以看到如果不使用dataclass装饰器,那么就只能手动去定义方法,使用dataclass则会非常简单方便。

下方给出更为详细的例子

class data:
    def __init__(self, x ,y):
        self.x = x
        self.y = y
    def __repr__(self):
        return f'data(x={self.x},y={self.y})'
    def __eq__(self,other):
        return self.x == other.x and self.y == other.y
    
d_a = data(1,2)
d_b = data(1,3)
print(d_a)
print(d_a == d_b)

输出

data(x=1,y=2)
False
from dataclasses import dataclass
 
@dataclass
class data:
    x: int
    y: int
 
# 使用数据类
d_a = data(1, 2)
d_b = data(1,3)
print(d_a)
print(d_a == d_b)

输出

data(x=1, y=2)
False

我们想要加其他功能时都需要在类中增加方法,而dataclass则将一些数据常用的方法封装好了,直接使用即可

比较方法

  • dataclass 默认不实现 __lt____le____gt____ge__ 方法,因此不能直接使用 <<=>>= 进行比较。可以通过在 @dataclass 装饰器中使用 order=True 参数,或者手动定义比较方法来实现。
  • 从 Python 3.11 开始,dataclasses 模块支持在 @dataclass 装饰器中使用 order=True 参数,自动生成比较方法。

自定义比较

from dataclasses import dataclass
 
@dataclass(order=True)
class data:
    x: int
    y: int
 
# 使用数据类
d_a = data(1, 2)
d_b = data(2, 3)
d_c = data(0, 4)
print(d_a)
print(d_a < d_b)
print(d_a < d_c)

 输出

data(x=1, y=2)
True
False

 注意:

  • 是从第一个字段(x)开始比较,如果大于则会返回false,否则继续比较下一个,比较完都是小于则返回true
  • 如果某一个字段比较的结果相等也会继续比较,如果所有字段比较结果都是相等会返回false,至少有一个比较结果是小于,并且没有结果是大于,则会返回true

手动定义比较方法

 

from dataclasses import dataclass
 
@dataclass
class data:
    x: int
    y: int
    
    def __lt__(self,other):
        if not isinstance(other,data):
            return data
        return self.x < other.x and self.y < other.y
    
     
# 使用数据类
d_a = data(1, 2)
d_b = data(2, 3)
d_c = data(1, 4)
print(d_a)
print(d_a < d_b)
print(d_a < d_c)

输出

data(x=1, y=2)
True
False

可以看到只有两个字段比较结果都是小于才返回true,这是因为在自己定义lt方法中使用的是and只有两个条件都满足才返回真

实例不可变

  • 当定义一个数据类时,可以通过在 @dataclass 装饰器中设置 frozen=True 来使其实例不可变。
  • 不可变实例意味着一旦创建,其属性值就不能被修改。这对于确保数据的一致性和防止意外修改非常有用。
from dataclasses import dataclass
 
@dataclass(frozen=True)
class data:
    x: int
    y: int
    
# 使用数据类
d_a = data(1, 2)

try:
    d_a.x = 0
except AttributeError as e:
    print(f'发生错误:{e}')
print(d_a)

 输出

发生错误:cannot assign to field 'x'
data(x=1, y=2)

后期初始化处理

  • 如果希望创建一个数据类实例并在后期(即实例化之后)进行某些初始化处理或设置一些属性,可以通过使用 __post_init__ 方法
  • 它允许在实例创建后执行自定义的初始化逻辑。可以在这个方法中进行属性的后期设置或验证。
from dataclasses import dataclass
 
@dataclass
class data:
    x: int
    y: int
    z: int = 0
    def __post_init__(self):
        self.z = self.x + self.y
    
# 使用数据类
d_a = data(1, 2)
print(d_a)

 输出

data(x=1, y=2, z=3)
  •  如果需要在实例化后动态地计算或设置某些属性,可以使用 property 装饰器。这允许定义一个方法来计算属性值,而不是在实例化时直接设置。
from dataclasses import dataclass
 
@dataclass
class data:
    x: int
    y: int
        
    @property
    def total(self):
        return self.x + self.y
    
# 使用数据类
d_a = data(1, 2)
print(f'结果是:{d_a.total}')

输出

结果是:3

 总结

  • 无需手动编写 __init__ 方法,dataclass 会根据定义的属性自动生成。
  • 自动生成 __repr__ 方法,便于调试和日志记录。
  • 自动生成 __eq__ 方法,用于比较两个实例是否相等。
  • 可选地生成 __lt____le____gt____ge__ 方法,用于排序。
  • 使用 __post_init__ 方法在实例创建后执行额外的初始化逻辑。
  • 通过设置 frozen=True,可以创建不可变实例。

你可能感兴趣的:(python,开发语言)