理解 Python 的 Dataclasses(二)

dataclasses

這是 Python 最新的 Dataclasses 系列的第二部分內(nèi)容。在第一部分里边翼,我介紹了dataclasses 的一般用法胆绊。這篇博客主要介紹另一個特征:dataclasses.field

我們已經(jīng)知道Dataclasses會生成他們自身的__init__方法聪轿。它同時把初始化的值賦給這些字段煤惩。以下是我們在上一篇博客里定義的內(nèi)容:

  • 變量名

  • 數(shù)據(jù)類型

這些內(nèi)容僅給我們有限的 dataclass字段使用范圍嫉嘀。讓我們討論一下這些局限性,以及它們?nèi)绾瓮ㄟ^ dataclass.field被解決魄揉。

復(fù)合初始化

考慮以下情形:你想要初始化一個變量為列表。你如何實(shí)現(xiàn)它呢拭宁?一種簡單的方式是使用__post_init__方法洛退。

dataclasses

數(shù)據(jù)類Student產(chǎn)生了一個名為marks 的列表。我們不傳遞 marks 的值杰标,而是使用__post_init__方法初始化兵怯。這是我們定義的單一屬性。此外腔剂,我們必須在__post_init__里調(diào)用get_random_marks 函數(shù)媒区。這些工作是額外的。

辛運(yùn)的是掸犬,Python為我們提供了一個解決方案袜漩。我們可以使用dataclasses.field來定制化 dataclass字段的行為以及它們在dataclass的影響。

仍然是上述的使用情形湾碎,讓我們從__post_init__里去除 get_random_marks 的調(diào)用宙攻。以下是使用dataclasses.field的情形:

dataclasses

dataclasses.field 接受了一個名為default_factory的參數(shù),它的作用是:如果在創(chuàng)建對象時沒有賦值介褥,則使用該方法初始化該字段座掘。

default_factory必須是一個可以調(diào)用的無參數(shù)方法(通常為一個函數(shù))。

這樣我們就可以使用復(fù)合形式初始化字段∪崽希現(xiàn)在溢陪,讓我們考慮另一個使用場景。

使用全部字段進(jìn)行數(shù)據(jù)比較

通過上篇博文睛廊,我們了解到形真,dataclass 能夠自動生成< ,=, >, <=>=這些比較方法。但是這些比較方法的一個缺陷是喉前,它們使用類中的所有字段進(jìn)行比較没酣,而這種情況往往不常見王财。更經(jīng)常地,這種比較方法會給我們使用 dataclasses造成麻煩裕便。

考慮以下的使用情形:你有一個數(shù)據(jù)類用于存放用戶的信息∪蘧唬現(xiàn)在,它可能存在以下字段:

  • 姓名

  • 年齡

  • 身高

  • 體重

你僅想比較用戶對象的年齡偿衰、身高和體重挂疆。你不想比較姓名。這是后端開發(fā)者經(jīng)常會遇到的使用情景下翎。


dataclass

自動生成的比較方法會比較一下的數(shù)組:

dataclass

這將會破壞我們的意圖缤言。我們不想讓姓名(name)用于比較。那么视事,如何使用 dataclasses.field來實(shí)現(xiàn)我們的想法呢胆萧?

下面是具體步驟:

dataclass

默認(rèn)情況下,所用的字段都用于比較俐东,因此我們僅僅需要指定哪些字段用于比較跌穗,而實(shí)現(xiàn)方法是直接把不需要的字段定義為filed(compare=False)

一個更為簡單的應(yīng)用情形也可以被討論虏辫。讓我們定義一個數(shù)據(jù)類蚌吸,它被用來存儲一個數(shù)字激起字符串表示。我們想讓比較僅僅發(fā)生在該數(shù)字的值砌庄,而不是他的字符串表示羹唠。


dataclass

現(xiàn)在,我們有更大的自由來控制 dataclasses 的行為娄昆∨逦ⅲ看起來很棒!

使用全部字段進(jìn)行數(shù)據(jù)表示

自動生成的__repr__方法使用所有的字段用于表示稿黄。當(dāng)然喊衫,這也不是大多數(shù)情形下的理想選擇,尤其是當(dāng)你的數(shù)據(jù)類有大量的字段時杆怕。單個對象的表示會變得異常臃腫族购,對調(diào)試來說也不利。

dataclass

想象一下在你的日志里看到這樣的表示吧陵珍,然后還要寫一個正則表達(dá)式來搜索它寝杖。太可怕了,對吧互纯?

當(dāng)然瑟幕,我們也能夠個性化這種行為。考慮一個類似的使用場景只盹,也許最合適的用于表示的屬性是姓名(name)辣往。那么對__repr__,我們僅使用它:

dataclass

這樣看起來就很棒了殖卑。調(diào)試很方便站削,比較也有意義!

從初始化中省略字段

目前為止我們看到的所有例子孵稽,都有一個共同特點(diǎn)——即我們需要為所有被聲明的字段傳遞值许起,除了有默認(rèn)值之外。在那種情形下(指有默認(rèn)值的情況下)菩鲜,我們可以選擇傳遞值园细,也可以不傳遞。

dataclass

但是接校,還有一種情形:我們可能不想在初始化時設(shè)定某個字段的值猛频。這也是一種常見的使用場景。也許你在追蹤一個對象的狀態(tài)馅笙,并且希望它在初始化時一直被設(shè)為 False伦乔。更一般地,這個值在初始化時不能夠被傳遞董习。
dataclass

那么,我們?nèi)绾螌?shí)現(xiàn)上述想法呢爱只?以下是具體內(nèi)容:

dataclass

瞧懊罅堋!我們現(xiàn)在對dataclasses的使用有了更大的靈活性恬试。

總結(jié)

希望上兩篇博文能夠幫助你理解dataclass窝趣,希望你能盡快在項(xiàng)目中使用它們!

感謝你的閱讀训柴。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末哑舒,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子幻馁,更是在濱河造成了極大的恐慌洗鸵,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件仗嗦,死亡現(xiàn)場離奇詭異膘滨,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)稀拐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進(jìn)店門火邓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事铲咨《愀欤” “怎么了?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵纤勒,是天一觀的道長坯苹。 經(jīng)常有香客問我,道長踊东,這世上最難降的妖魔是什么北滥? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮闸翅,結(jié)果婚禮上再芋,老公的妹妹穿的比我還像新娘。我一直安慰自己坚冀,他們只是感情好济赎,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著记某,像睡著了一般司训。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上液南,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天壳猜,我揣著相機(jī)與錄音,去河邊找鬼滑凉。 笑死统扳,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的畅姊。 我是一名探鬼主播咒钟,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼若未!你這毒婦竟也來了朱嘴?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤粗合,失蹤者是張志新(化名)和其女友劉穎萍嬉,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體舌劳,經(jīng)...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡帚湘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了甚淡。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片大诸。...
    茶點(diǎn)故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡捅厂,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出资柔,到底是詐尸還是另有隱情焙贷,我是刑警寧澤,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布贿堰,位于F島的核電站辙芍,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏羹与。R本人自食惡果不足惜故硅,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望纵搁。 院中可真熱鬧吃衅,春花似錦、人聲如沸腾誉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽利职。三九已至趣效,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間猪贪,已是汗流浹背跷敬。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留热押,地道東北人干花。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像楞黄,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子抡驼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,691評論 2 361

推薦閱讀更多精彩內(nèi)容