一文详解python中dataclass的使用技巧

 更新时间:2024年03月18日 08:20:38   作者:databook  
dataclass是从Python3.7版本开始,作为标准库中的模块被引入,随着Python版本的不断更新,dataclass也逐步发展和完善,为Python开发者提供了更加便捷的数据类创建和管理方式,本文总结了几个我平时使用较多dataclass技巧,需要的朋友可以参考下

引言

dataclass是从Python3.7版本开始,作为标准库中的模块被引入。
随着Python版本的不断更新,dataclass也逐步发展和完善,为Python开发者提供了更加便捷的数据类创建和管理方式。

dataclass的主要功能在于帮助我们简化数据类的定义过程。
本文总结了几个我平时使用较多dataclass技巧。

1. 传统的类定义方式

首先,从平时量化分析的场景中简化一个关于 币交易 的类用来演示。
简化之后,这里只保留5个字段,分别是交易ID交易对价格是否成功参与交易的地址列表

class CoinTrans:
    def __init__(
        self,
        id: str,
        symbol: str,
        price: float,
        is_success: bool,
        addrs: list,
    ) -> None:
        self.id = id
        self.symbol = symbol
        self.price = price
        self.addrs = addrs
        self.is_success = is_success

Python传统定义类的方式,如上通过__init__函数来初始化对象的各个属性。

通过这个类构造对象并打印:

if __name__ == "__main__":
    coin_trans = CoinTrans("id01", "BTC/USDT", "71000", True, ["0x1111", "0x2222"])
    print(coin_trans)

运行结果:

<__main__.CoinTrans object at 0x0000022A891FADD0>

这里只是打印出对象的地址,并没有按照我们期望的那样打印对象各个属性的值。

传统的类中,我们如果希望打印出可读的结果,需要自己去实现__str__函数。

# 在上面的 CoinTrans 类中添加下面的方法
def __str__(self) -> str:
    return f"交易信息:{self.id}, {self.symbol}, {self.price}, {self.addrs}, {self.is_success}"

再次运行,结果如下:

交易信息:id01, BTC/USDT, 71000, ['0x1111', '0x2222'], True

2. dataclass装饰器定义类

下面看看使用dataclass装饰器来定义上面同样的类有多简单。

from dataclasses import dataclass

@dataclass
class CoinTrans:
    id: str
    symbol: str
    price: float
    is_success: bool
    addrs: list

再次运行:

if __name__ == "__main__":
    coin_trans = CoinTrans("id01", "BTC/USDT", "71000", True, ["0x1111", "0x2222"])
    print(coin_trans)

得到如下结果:

CoinTrans(id='id01', symbol='BTC/USDT', price='71000', is_success=True, addrs=['0x1111', '0x2222'])

不需要__init__,也不需要__str__,只要通过 @dataclass装饰之后,就可以打印出对象的具体内容。

2.1. 默认值

dataclass装饰器的方式来定义类,设置默认值很简单,直接在定义属性时就可以设置。

@dataclass
class CoinTrans:
    id: str = "id01"
    symbol: str = "BTC/USDT"
    price: float = "71000.8"
    is_success: bool = True
    addrs: list[str] = ["0x1111", "0x2222"]

if __name__ == "__main__":
    coin_trans = CoinTrans()
    print(coin_trans)

运行之后发现,在addrs属性那行会报错:

ValueError: mutable default <class 'list'> for field addrs is not allowed: use default_factory

大概的意思就是,list作为一种可变的类型(引用类型,会有被其他对象意外修改的风险),不能直接作为默认值,需要用工厂方法来产生默认值。
其他字符串,数值,布尔类型的数据则没有这个问题。

我们只要定义个函数来产生此默认值即可。

def gen_list():
    return ["0x1111", "0x2222"]

@dataclass
class CoinTrans:
    id: str = "id01"
    symbol: str = "BTC/USDT"
    price: float = "71000.8"
    is_success: bool = True
    addrs: list[str] = field(default_factory=gen_list)

if __name__ == "__main__":
    coin_trans = CoinTrans()
    print(coin_trans)

再次运行,可以正常执行:

CoinTrans(id='id01', symbol='BTC/USDT', price='71000.8', is_success=True, addrs=['0x1111', '0x2222']

2.2. 隐藏敏感信息

我们打印对象信息的时候,有时执行打印其中几个属性的信息,涉及敏感信息的属性不希望打印出来。
比如,上面的对象,如果不想打印出is_successaddrs的信息,可以设置repr=False

@dataclass
class CoinTrans:
    id: str = "id01"
    symbol: str = "BTC/USDT"
    price: float = "71000.8"
    is_success: bool = field(default=True, repr=False)
    addrs: list[str] = field(default_factory=gen_list, repr=False)

再次运行后显示:

CoinTrans(id='id01', symbol='BTC/USDT', price='71000.8')

2.3. 只读对象

数据分析时,大部分下情况下,原始数据读取之后是不能修改的。
这种情况下,我们可以用dataclassfrozen属性来设置数据类只读,防止不小心篡改了数据。

未设置frozen属性之前,可以随意修改对象的属性,比如:

if __name__ == "__main__":
    coin_trans = CoinTrans()
    print(f"修改前: {coin_trans}")
    coin_trans.symbol = "ETH/USDT"
    print(f"修改后: {coin_trans}")

运行结果:

修改前: CoinTrans(id='id01', symbol='BTC/USDT', price='71000.8')
修改后: CoinTrans(id='id01', symbol='ETH/USDT', price='71000.8')

设置frozen属性之后,看看修改属性值会怎么样:

@dataclass(frozen=True)
class CoinTrans:
    id: str = "id01"
    #... 省略 ...

再次运行,会发现修改属性会触发异常。

修改前: CoinTrans(id='id01', symbol='BTC/USDT', price='71000.8')
Traceback (most recent call last):
  File "D:\projects\python\samples\data_classes\main.py", line 66, in <module>
    coin_trans.symbol = "ETH/USDT"
    ^^^^^^^^^^^^^^^^^
  File "<string>", line 4, in __setattr__
dataclasses.FrozenInstanceError: cannot assign to field 'symbol'

2.4. 转化为元组和字典

最后,dataclasses模块还提供了两个函数可以很方便的将数据类转换为元组字典
这在和其他分析程序交互时非常有用,因为和其他程序交互时,参数一般都用元组或者字典这种简单通用的结构,
而不会直接用自己定义的数据类。

from dataclasses import dataclass, field, astuple, asdict

if __name__ == "__main__":
    coin_trans = CoinTrans()
    print(astuple(coin_trans))
    print(asdict(coin_trans))

运行结果:

('id01', 'BTC/USDT', '71000.8', True, ['0x1111', '0x2222'])
{'id': 'id01', 'symbol': 'BTC/USDT', 'price': '71000.8', 'is_success': True, 'addrs': ['0x1111', '0x2222']}

3. 总结

Python中,数据类主要用于存储数据,并通常包含属性和方法来操作这些数据。
然而,在定义数据类时,我们通常需要编写一些重复性的代码,如构造函数、属性访问器和字符串表示等。
dataclass装饰器的出现,使得这些通用方法的生成变得自动化,从而极大地简化了数据类的定义过程。

总的来说,dataclass通过简化数据类的创建和管理过程,提高了开发效率,是我们在数据分析时的一个非常有用的工具。

以上就是一文详解python中dataclass的使用技巧的详细内容,更多关于python dataclass使用的资料请关注脚本之家其它相关文章!

相关文章

  • Python Web框架之Django框架Model基础详解

    Python Web框架之Django框架Model基础详解

    这篇文章主要介绍了Python Web框架之Django框架Model基础,结合实例形式分析了Django框架Model模型相关使用技巧与操作注意事项,需要的朋友可以参考下
    2019-08-08
  • 基于Python获取城市近7天天气预报

    基于Python获取城市近7天天气预报

    这篇文章主要介绍了基于Python获取城市近7天天气预报,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • 关于Python 内置库 itertools

    关于Python 内置库 itertools

    今天得这篇文章就来给大家介绍一下Python的系统库itertools的 相关资料,需要的小伙伴可以参考下面文章的具体内容
    2021-09-09
  • PyTorch一小时掌握之图像识别实战篇

    PyTorch一小时掌握之图像识别实战篇

    这篇文章主要介绍了PyTorch一小时掌握之图像识别实战篇,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-09-09
  • PyQt转换路径中的斜杠(斜杠(/)与反斜杠(\)转换)

    PyQt转换路径中的斜杠(斜杠(/)与反斜杠(\)转换)

    本文主要介绍了PyQt转换路径中的斜杠(斜杠(/)与反斜杠(\)转换),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • Python语法学习之正则表达式的量词汇总

    Python语法学习之正则表达式的量词汇总

    通过正则的规则匹配到的信息都是一个单独的字符存到输出结果中的,如何更够根据字符串中的词组进行匹配呢?因此本文将带大家学习一下正则表达式中的量词符号与组的概念,感兴趣的可以了解一下
    2022-04-04
  • Python控制台输出俄罗斯方块的方法实例

    Python控制台输出俄罗斯方块的方法实例

    这篇文章主要给大家介绍了关于Python控制台输出俄罗斯方块的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • Pycharm配置远程SSH服务器实现(切换不同虚拟环境)

    Pycharm配置远程SSH服务器实现(切换不同虚拟环境)

    本文主要介绍了Pycharm配置远程SSH服务器实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-02-02
  • 分位数回归模型quantile regeression应用详解及示例教程

    分位数回归模型quantile regeression应用详解及示例教程

    这篇文章主要为大家介绍了介绍了分位数回归quantile regeression的概念详解及代码示例教程,有需要的朋友可以借鉴参考下,希望能够有所帮助
    2021-11-11
  • Python tracemalloc跟踪内存分配问题

    Python tracemalloc跟踪内存分配问题

    这篇文章主要介绍了Python tracemalloc跟踪内存分配问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11

最新评论