一文詳解python中dataclass的使用技巧
引言
dataclass
是從Python3.7
版本開始,作為標(biāo)準(zhǔn)庫(kù)中的模塊被引入。
隨著Python
版本的不斷更新,dataclass
也逐步發(fā)展和完善,為Python
開發(fā)者提供了更加便捷的數(shù)據(jù)類創(chuàng)建和管理方式。
dataclass
的主要功能在于幫助我們簡(jiǎn)化數(shù)據(jù)類的定義過程。
本文總結(jié)了幾個(gè)我平時(shí)使用較多dataclass
技巧。
1. 傳統(tǒng)的類定義方式
首先,從平時(shí)量化分析的場(chǎng)景中簡(jiǎn)化一個(gè)關(guān)于 幣交易 的類用來(lái)演示。
簡(jiǎn)化之后,這里只保留5個(gè)字段,分別是交易ID,交易對(duì),價(jià)格,是否成功和參與交易的地址列表。
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
傳統(tǒng)定義類的方式,如上通過__init__
函數(shù)來(lái)初始化對(duì)象的各個(gè)屬性。
通過這個(gè)類構(gòu)造對(duì)象并打印:
if __name__ == "__main__": coin_trans = CoinTrans("id01", "BTC/USDT", "71000", True, ["0x1111", "0x2222"]) print(coin_trans)
運(yùn)行結(jié)果:
<__main__.CoinTrans object at 0x0000022A891FADD0>
這里只是打印出對(duì)象的地址,并沒有按照我們期望的那樣打印對(duì)象各個(gè)屬性的值。
傳統(tǒng)的類中,我們?nèi)绻M蛴〕隹勺x的結(jié)果,需要自己去實(shí)現(xiàn)__str__
函數(shù)。
# 在上面的 CoinTrans 類中添加下面的方法 def __str__(self) -> str: return f"交易信息:{self.id}, {self.symbol}, {self.price}, {self.addrs}, {self.is_success}"
再次運(yùn)行,結(jié)果如下:
交易信息:id01, BTC/USDT, 71000, ['0x1111', '0x2222'], True
2. dataclass裝飾器定義類
下面看看使用dataclass
裝飾器來(lái)定義上面同樣的類有多簡(jiǎn)單。
from dataclasses import dataclass @dataclass class CoinTrans: id: str symbol: str price: float is_success: bool addrs: list
再次運(yùn)行:
if __name__ == "__main__": coin_trans = CoinTrans("id01", "BTC/USDT", "71000", True, ["0x1111", "0x2222"]) print(coin_trans)
得到如下結(jié)果:
CoinTrans(id='id01', symbol='BTC/USDT', price='71000', is_success=True, addrs=['0x1111', '0x2222'])
不需要__init__
,也不需要__str__
,只要通過 @dataclass
裝飾之后,就可以打印出對(duì)象的具體內(nèi)容。
2.1. 默認(rèn)值
dataclass
裝飾器的方式來(lái)定義類,設(shè)置默認(rèn)值很簡(jiǎn)單,直接在定義屬性時(shí)就可以設(shè)置。
@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)
運(yùn)行之后發(fā)現(xiàn),在addrs
屬性那行會(huì)報(bào)錯(cuò):
ValueError: mutable default <class 'list'> for field addrs is not allowed: use default_factory
大概的意思就是,list
作為一種可變的類型(引用類型,會(huì)有被其他對(duì)象意外修改的風(fēng)險(xiǎn)),不能直接作為默認(rèn)值,需要用工廠方法來(lái)產(chǎn)生默認(rèn)值。
其他字符串,數(shù)值,布爾類型的數(shù)據(jù)則沒有這個(gè)問題。
我們只要定義個(gè)函數(shù)來(lái)產(chǎn)生此默認(rèn)值即可。
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)
再次運(yùn)行,可以正常執(zhí)行:
CoinTrans(id='id01', symbol='BTC/USDT', price='71000.8', is_success=True, addrs=['0x1111', '0x2222']
2.2. 隱藏敏感信息
我們打印對(duì)象信息的時(shí)候,有時(shí)執(zhí)行打印其中幾個(gè)屬性的信息,涉及敏感信息的屬性不希望打印出來(lái)。
比如,上面的對(duì)象,如果不想打印出is_success
和addrs
的信息,可以設(shè)置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)
再次運(yùn)行后顯示:
CoinTrans(id='id01', symbol='BTC/USDT', price='71000.8')
2.3. 只讀對(duì)象
數(shù)據(jù)分析時(shí),大部分下情況下,原始數(shù)據(jù)讀取之后是不能修改的。
這種情況下,我們可以用dataclass
的frozen
屬性來(lái)設(shè)置數(shù)據(jù)類只讀,防止不小心篡改了數(shù)據(jù)。
未設(shè)置frozen
屬性之前,可以隨意修改對(duì)象的屬性,比如:
if __name__ == "__main__": coin_trans = CoinTrans() print(f"修改前: {coin_trans}") coin_trans.symbol = "ETH/USDT" print(f"修改后: {coin_trans}")
運(yùn)行結(jié)果:
修改前: CoinTrans(id='id01', symbol='BTC/USDT', price='71000.8')
修改后: CoinTrans(id='id01', symbol='ETH/USDT', price='71000.8')
設(shè)置frozen
屬性之后,看看修改屬性值會(huì)怎么樣:
@dataclass(frozen=True) class CoinTrans: id: str = "id01" #... 省略 ...
再次運(yùn)行,會(huì)發(fā)現(xiàn)修改屬性會(huì)觸發(fā)異常。
修改前: 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. 轉(zhuǎn)化為元組和字典
最后,dataclasses
模塊還提供了兩個(gè)函數(shù)可以很方便的將數(shù)據(jù)類轉(zhuǎn)換為元組和字典。
這在和其他分析程序交互時(shí)非常有用,因?yàn)楹推渌绦蚪换r(shí),參數(shù)一般都用元組或者字典這種簡(jiǎn)單通用的結(jié)構(gòu),
而不會(huì)直接用自己定義的數(shù)據(jù)類。
from dataclasses import dataclass, field, astuple, asdict if __name__ == "__main__": coin_trans = CoinTrans() print(astuple(coin_trans)) print(asdict(coin_trans))
運(yùn)行結(jié)果:
('id01', 'BTC/USDT', '71000.8', True, ['0x1111', '0x2222'])
{'id': 'id01', 'symbol': 'BTC/USDT', 'price': '71000.8', 'is_success': True, 'addrs': ['0x1111', '0x2222']}
3. 總結(jié)
在Python
中,數(shù)據(jù)類主要用于存儲(chǔ)數(shù)據(jù),并通常包含屬性和方法來(lái)操作這些數(shù)據(jù)。
然而,在定義數(shù)據(jù)類時(shí),我們通常需要編寫一些重復(fù)性的代碼,如構(gòu)造函數(shù)、屬性訪問器和字符串表示等。dataclass
裝飾器的出現(xiàn),使得這些通用方法的生成變得自動(dòng)化,從而極大地簡(jiǎn)化了數(shù)據(jù)類的定義過程。
總的來(lái)說(shuō),dataclass
通過簡(jiǎn)化數(shù)據(jù)類的創(chuàng)建和管理過程,提高了開發(fā)效率,是我們?cè)跀?shù)據(jù)分析時(shí)的一個(gè)非常有用的工具。
以上就是一文詳解python中dataclass的使用技巧的詳細(xì)內(nèi)容,更多關(guān)于python dataclass使用的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- 深入理解Python?@dataclass的內(nèi)部原理
- Python 中的 dataclass使用場(chǎng)景與代碼示例詳解
- python dataclass 快速創(chuàng)建數(shù)據(jù)類的方法
- python 數(shù)據(jù)類(dataclass)的具體使用
- Python中dataclass庫(kù)實(shí)例詳解
- Python3.7 新特性之dataclass裝飾器
- Python3.7 dataclass使用指南小結(jié)
- Python 3.7新功能之dataclass裝飾器詳解
- 輕松掌握python的dataclass讓你的代碼更簡(jiǎn)潔優(yōu)雅
相關(guān)文章
pycharm設(shè)置python文件模板信息過程圖解
這篇文章主要介紹了pycharm設(shè)置python文件模板信息過程圖解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03利用Python進(jìn)行數(shù)據(jù)清洗的操作指南
數(shù)據(jù)清洗是指發(fā)現(xiàn)并糾正數(shù)據(jù)文件中可識(shí)別的錯(cuò)誤的最后一道程序,包括檢查數(shù)據(jù)一致性,處理無(wú)效值和缺失值等。本文為大家介紹了Python進(jìn)行數(shù)據(jù)清洗的操作詳解,需要的可以參考一下2022-03-03python+pygame實(shí)現(xiàn)簡(jiǎn)易五子棋小游戲的三種方式
這篇文章主要介紹了使用python實(shí)現(xiàn)簡(jiǎn)易五子棋小游戲,文中提供了三種實(shí)現(xiàn)方式,解決思路和部分實(shí)現(xiàn)代碼,感興趣的朋友可以參考下2023-03-03Python針對(duì)不同文本長(zhǎng)度的處理方案總結(jié)與對(duì)比
這篇文章主要為大家詳細(xì)介紹了Python如何針對(duì)不同文本長(zhǎng)度的處理方案,結(jié)合層次化編碼和檢索優(yōu)化策略,感興趣的小伙伴可以參考一下2025-02-02一種Python工具的License授權(quán)機(jī)制詳解
這篇文章主要介紹了一種Python工具的License授權(quán)機(jī)制,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06Python中卷積神經(jīng)網(wǎng)絡(luò)(CNN)入門教程分分享
卷積神經(jīng)網(wǎng)絡(luò)(Convolutional Neural Networks, CNN)是一類特別適用于處理圖像數(shù)據(jù)的深度學(xué)習(xí)模型,本文介紹了如何使用Keras創(chuàng)建一個(gè)簡(jiǎn)單的CNN模型,并用它對(duì)手寫數(shù)字進(jìn)行分類,需要的可以參考一下2023-05-05Python使用pandas將表格數(shù)據(jù)進(jìn)行處理
這篇文章主要介紹了Python使用pandas將表格數(shù)據(jù)進(jìn)行處理,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,感興趣的小伙伴可以參考一下2022-08-08基于python3 的百度圖片下載器的實(shí)現(xiàn)代碼
這篇文章主要介紹了基于python3 的百度圖片下載器的實(shí)現(xiàn)代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11嘗試用最短的Python代碼來(lái)實(shí)現(xiàn)服務(wù)器和代理服務(wù)器
"人生苦短、我用Python",Python最大的特點(diǎn)便是代碼簡(jiǎn)潔,得益于Python自帶的wsgiref包和socket模塊,這里我們將嘗試用最短的Python代碼來(lái)實(shí)現(xiàn)服務(wù)器和代理服務(wù)器:2016-06-06