熱線電話:13121318867

登錄
首頁精彩閱讀沒想到啊,Python類還可以這樣寫,簡潔又強大
沒想到啊,Python類還可以這樣寫,簡潔又強大
2022-08-26
收藏

作者:麥叔

來源:麥叔編程


回顧和問題

上一篇文章,我們講解了NamedTuple。它可以讓我們像使用對象一樣使用元組,避免魔術數字,讓代碼更安全,更易于理解,也比普通對象更快。

下面是其中的例子。有興趣的麥友可以在合集中往前翻,找到上一篇文章。

from typing import NamedTuple class Stock(NamedTuple): name: str
    high: float
    low: float
    end: float

stock1 = Stock('蘋果', 100, 80, 88)
stock2 = Stock(name='百度', high=80, low=63, end=65)

print(stock2.high)
print(stock2.low)
print(stock2.end)

但命名元組有個問題。它的數據是不能修改的,這是元組的重要特點。

那如果我的對象需要修改,怎么辦呢?這就是本文的重點!

使用dataclass

從Python3.7開始,我們可以用很簡潔的語法定義只有屬性的類,也就是dataclass。從表面上看,它們非常像命名元組。

下面是dataclass版本的Stock:

from dataclasses import dataclass
@dataclass class Stock: symbol: str
    current: float high: float low: float 

這個例子中,它的定義幾乎和NamedTuple定義完全相同。

dataclass函數是一個類裝飾器,使用@符號。dataclass 包含狀態且可以被修改,重要的是它的功能很強大。

下面是創建Stock實例的例子:

>>> s = Stock("AAPL", 123.52, 137.98, 53.15)

一旦實例化,Stock對象可以像普通類一樣使用。你可以訪問和更新它的屬性:

>>> s
Stock(symbol='AAPL', current=123.52, high=137.98, low=53.15) >>> s.current 123.52 >>> s.current = 122.25 >>> s
Stock(symbol='AAPL', current=122.25, high=137.98, low=53.15)

優點多多

我們來看看,dataclass相比普通的類有什么優點。

下面是一個功能類似的普通類:

class StockOrdinary: def __init__(self, name: str, current: float, high: float, low: float) -> None: self.name = name self.current = current self.high = high self.low = low
s_ord = StockOrdinary("AAPL", 123.52, 137.98, 53.15)

「好處1」:dataclass只需要寫一次屬性名,不需要在__init__()方法的參數和方法體中重復。

「好處2」:dataclass也提供了一個比object類更加友好的字符串表達。

「好處3」:dataclass也包含相等比較運算。

下面的例子可以比較普通類和dataclass的區別:

>>> s_ord
<__main__.StockOrdinary object at 0x7fb833c63f10> >>> s_ord_2 = StockOrdinary("AAPL", 123.52, 137.98, 53.15) >>> s_ord == s_ord_2
False

普通類的默認字符串表達看起來很糟糕,而且它沒有相等運算。dataclass的情況就要好多了:

>>> stock2 = Stock(symbol='AAPL', current=122.25, high=137.98, low=53.15) >>> s == stock2
True

「好處4」:你可以為屬性指定默認值。

也許股票市場閉市了,你不知道今天股票的價格是什么:

@dataclass class StockDefaults: name: str current: float = 0.0 high: float = 0.0 low: float = 0.0 

你可以只用股票名稱來創建對象。其他的值會使用默認值:

>>> StockDefaults("GOOG") StockDefaults(name='GOOG', current=0.0, high=0.0, low=0.0)

「好處5」:你可以輕松的添加比較運算,如下所示:

@dataclass(order=True) class StockOrdered: name: str current: float = 0.0 high: float = 0.0 low: float = 0.0 

你也許會問:就這么簡單?

是的!給裝飾器添加order=True參數,就會創建所有的比較運算方法。這使得我們可以比較對象實例,也可以排序。就像下面這樣:

>>> stock_ordered1 = StockOrdered("GOOG", 1826.77, 1847.20, 1013.54) >>> stock_ordered2 = StockOrdered("GOOG") >>> stock_ordered3 = StockOrdered("GOOG", 1728.28, high=1733.18, 
low=1666.33) >>> stock_ordered1 < stock_ordered2
False >>> stock_ordered1 > stock_ordered2
True >>> from pprint import pprint >>> pprint(sorted([stock_ordered1, stock_ordered2, stock_ordered3]))
[StockOrdered(name='GOOG', current=0.0, high=0.0, low=0.0),
 StockOrdered(name='GOOG', current=1728.28, high=1733.18, low=1666.33),
 StockOrdered(name='GOOG', current=1826.77, high=1847.2, low=1013.54)]

麥叔寄語

下次創建類的時候,試試看 @dataclass,寫很少的代碼就有很強大的功能。

dataclass也可以像普通類一樣,添加所需要的實例方法或類方法。

數據分析咨詢請掃描二維碼

若不方便掃碼,搜微信號:CDAshujufenxi

數據分析師資訊
更多

OK
客服在線
立即咨詢
日韩人妻系列无码专区视频,先锋高清无码,无码免费视欧非,国精产品一区一区三区无码
客服在線
立即咨詢