欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python中最神秘missing()函數(shù)介紹

 更新時間:2021年12月23日 08:47:02   作者:晨xi的光  
大家好,本篇文章主要講的是Python中最神秘missing()函數(shù)介紹,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽

前言

一個非常神秘的魔術(shù)方法。

這個方法非常不起眼,用途狹窄,我?guī)缀鯊奈醋⒁膺^它,然而,當(dāng)發(fā)現(xiàn)它可能是上述“定律”的唯一例外情況時,我認(rèn)為值得再寫一篇文章來詳細(xì)審視一下它。

本文主要關(guān)注的問題有:

(1)?missing()到底是何方神圣?

(2)?missing()有什么特別之處?擅長“大變活人”魔術(shù)?

(3)?missing()是否真的是上述發(fā)現(xiàn)的例外?如果是的話,為什么會有這種特例?

1、有點(diǎn)價(jià)值的missing()

從普通的字典中取值時,可能會出現(xiàn) key 不存在的情況:

dd = {'name':'PythonCat'}
dd.get('age')        # 結(jié)果:None
dd.get('age', 18)    # 結(jié)果:18
dd['age']            # 報(bào)錯 KeyError
dd.__getitem__('age')  # 等同于 dd['age']

對于 get() 方法,它是有返回值的,而且可以傳入第二個參數(shù),作為 key 不存在時的返回內(nèi)容,因此還可以接受。但是,另外兩種寫法都會報(bào)錯。

為了解決后兩種寫法的問題,就可以用到?missing() 魔術(shù)方法。

現(xiàn)在,假設(shè)我們有一個這樣的訴求:從字典中取某個 key 對應(yīng)的 value,如果有值則返回值,如果沒有值則插入 key,并且給它一個默認(rèn)值(例如一個空列表)。

如果用原生的 dict,并不太好實(shí)現(xiàn),但是,Python 提供了一個非常好用的擴(kuò)展類collections.defaultdict

如圖所示,當(dāng)取不存在的 key 時,沒有再報(bào) KeyError,而是默認(rèn)存入到字典中。

為什么 defaultdict 可以做到這一點(diǎn)呢?

原因是 defaultdict 在繼承了內(nèi)置類型 dict 之后,還定義了一個?missing() 方法,當(dāng)?getitem取不存在的值時,它就會調(diào)用入?yún)⒅袀魅氲墓S函數(shù)(上例是調(diào)用 list(),創(chuàng)建空列表)。

作為最典型的示例,defaultdict 在文檔注釋中寫到:

簡而言之,missing()的主要作用就是由getitem在缺失 key 時調(diào)用,從而避免出現(xiàn) KeyError。

另外一個典型的使用例子是collections.Counter,它也是 dict 的子類,在取未被統(tǒng)計(jì)的 key 時,返回計(jì)數(shù) 0:

2、神出鬼沒的missing()

由上可知,missing()在getitem()取不到值時會被調(diào)用,但是,我不經(jīng)意間還發(fā)現(xiàn)了一個細(xì)節(jié):getitem()在取不到值時,并不一定會調(diào)用missing()。

這是因?yàn)樗⒎莾?nèi)置類型的必要屬性,并沒有在字典基類中被預(yù)先定義。

如果你直接從 dict 類型中取該屬性值,會報(bào)屬性不存在:AttributeError: type object 'object' has no attribute '__missing__'。

使用 dir() 查看,發(fā)現(xiàn)確實(shí)不存在該屬性:

如果從 dict 的父類即 object 中查看,也會發(fā)現(xiàn)同樣的結(jié)果。

這是怎么回事呢?為什么在 dict 和 object 中都沒有missing屬性呢?

然而,查閱最新的官方文檔,object 中分明包含這個屬性:

出處:3. Data model — Python 3.10.1 documentationmissing#object.missing

也就是說,理論上 object 類中會預(yù)定義missing,其文檔證明了這一點(diǎn),然而實(shí)際上它并沒有被定義!文檔與現(xiàn)實(shí)出現(xiàn)了偏差!

如此一來,當(dāng) dict 的子類(例如 defaultdict 和 Counter)在定義missing?時,這個魔術(shù)方法事實(shí)上只屬于該子類,也就是說,它是一個誕生于子類中的魔術(shù)方法!

據(jù)此,我有一個不成熟的猜想:getitem()會判斷當(dāng)前對象是否是 dict 的子類,且是否擁有missing(),然后才會去調(diào)用它(如果父類中也有該方法,則不會先作判斷,而是直接就調(diào)用了)。

我在交流群里說出了這個猜想,有同學(xué)很快在 CPython 源碼中找到驗(yàn)證:

而這就有意思了,在內(nèi)置類型的子類上才存在的魔術(shù)方法,縱觀整個 Python 世界,恐怕再難以找出第二例。

我突然有一個聯(lián)想:這神出鬼沒的missing(),就像是一個擅長玩“大變活人”的魔術(shù)師,先讓觀眾在外面透過玻璃看到他(即官方文檔),然而揭開門時,他并不在里面(即內(nèi)置類型),再變換一下道具,他又完好無損就出現(xiàn)了(即 dict 的子類)。

3、被施魔法的missing()

missing() 的神奇之處,除了它本身會變“魔術(shù)”之外,它還需要一股強(qiáng)大的“魔法”才能驅(qū)動。

我發(fā)現(xiàn)原生的魔術(shù)方法間相互獨(dú)立,它們在 C 語言界面可能有相同的核心邏輯,但是在 Python 語言界面,卻并不存在著調(diào)用關(guān)系:

魔術(shù)方法的這種“老死不相往來”的表現(xiàn),違背了一般的代碼復(fù)用原則,也是導(dǎo)致內(nèi)置類型的子類會出現(xiàn)某些奇怪表現(xiàn)的原因。

官方 Python 寧肯提供新的 UserString、UserList、UserDict 子類,也不愿意復(fù)用魔術(shù)方法,唯一合理的解釋似乎是令魔術(shù)方法相互調(diào)用的代價(jià)太大。

但是,對于特例missing(),Python 卻不得不妥協(xié),不得不付出這種代價(jià)!

missing() 是魔術(shù)方法的“二等公民”,它沒有獨(dú)立的調(diào)用入口,只能被動地由?getitem() 調(diào)用,即missing() 依賴于getitem()。

不同于那些“一等公民”,例如?init()、enter()、len()、eq() 等等,它們要么是在對象生命周期或執(zhí)行過程的某個節(jié)點(diǎn)被觸發(fā),要么由某個內(nèi)置函數(shù)或操作符觸發(fā),這些都是相對獨(dú)立的事件,無所依賴。

missing() 依賴于getitem(),才能實(shí)現(xiàn)方法調(diào)用;而?getitem() 也要依賴?missing(),才能實(shí)現(xiàn)完整功能。

為了實(shí)現(xiàn)這一點(diǎn),getitem()在解釋器代碼中開了個后門,從 C 語言界面折返回 Python 界面,去調(diào)用那個名為“missing”的特定方法。

而這就是真正的“魔法”了,目前為止,missing()似乎是唯一一個享受了此等待遇的魔術(shù)方法!

4、小結(jié)

Python 的字典提供了兩種取值的內(nèi)置方法,即getitem() 和 get(),當(dāng)取值不存在時,它們的處理策略是不一樣的:前者會報(bào)錯KeyError,而后者會返回 None。

為什么 Python 要提供兩個不同的方法呢?或者應(yīng)該問,為什么 Python 要令這兩個方法做出不一樣的處理呢?

這可能有一個很復(fù)雜(也可能是很簡單)的解釋,本文暫不深究了。

不過有一點(diǎn)是可以確定的:即原生 dict 類型簡單粗暴地拋KeyError的做法有所不足。

為了讓字典類型有更強(qiáng)大的表現(xiàn)(或者說讓getitem()作出 get() 那樣的表現(xiàn)),Python 讓字典的子類可以定義missing(),供getitem()查找調(diào)用。

本文梳理了missing()的實(shí)現(xiàn)原理,從而揭示出它并非是一個毫不起眼的存在,恰恰相反,它是唯一一個打破了魔術(shù)方法間壁壘,支持被其它魔術(shù)方法調(diào)用的特例!

Python 為了維持魔術(shù)方法的獨(dú)立性,不惜煞費(fèi)苦心地引入了 UserString、UserList、UserDict 這些派生類,但是對于?missing(),它卻選擇了妥協(xié)。

到此這篇關(guān)于Python中最神秘missing()函數(shù)介紹的文章就介紹到這了,更多相關(guān)Python missing()函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python學(xué)習(xí)之日志模塊詳解

    Python學(xué)習(xí)之日志模塊詳解

    說到日志,我們完全可以想象為現(xiàn)實(shí)生活中的日記。日記是我們平時記錄我們生活中點(diǎn)點(diǎn)滴滴的一種方法,而日志我們可以認(rèn)為是 程序的日記 ,程序的日記是用來記錄程序的行為。本文將詳細(xì)介紹Python中的日志模塊(logging),需要的可以參考一下
    2022-03-03
  • 關(guān)于Python的Thread線程模塊詳解

    關(guān)于Python的Thread線程模塊詳解

    這篇文章主要介紹了關(guān)于Python的Thread線程模塊詳解,進(jìn)程是程序的一次執(zhí)行,每個進(jìn)程都有自己的地址空間、內(nèi)存、數(shù)據(jù)棧以及其他記錄其運(yùn)行的輔助數(shù)據(jù),需要的朋友可以參考下
    2023-05-05
  • Jupyter Notebook切換conda虛擬環(huán)境的實(shí)現(xiàn)步驟

    Jupyter Notebook切換conda虛擬環(huán)境的實(shí)現(xiàn)步驟

    本文主要介紹了Jupyter Notebook切換conda虛擬環(huán)境的實(shí)現(xiàn)步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • 如何快速理解python的垃圾回收機(jī)制

    如何快速理解python的垃圾回收機(jī)制

    在本篇內(nèi)容里小編給各位分享的是一篇關(guān)于如何快速理解python的垃圾回收機(jī)制的相關(guān)知識點(diǎn)內(nèi)容,需要的朋友們可以學(xué)習(xí)下。
    2020-09-09
  • Python中窗口操作的完整教程

    Python中窗口操作的完整教程

    在使用 Python 進(jìn)行窗口操作時,可以執(zhí)行各種任務(wù),如最大化、最小化、置頂窗口,本文將詳細(xì)介紹這些操作,并提供豐富的示例代碼,希望可以更好地幫助大家了解如何利用 Python 操縱窗口
    2023-11-11
  • python之yield和Generator深入解析

    python之yield和Generator深入解析

    這篇文章主要介紹了python之yield和Generator深入解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09
  • Matplotlib實(shí)戰(zhàn)之堆疊面積圖繪制詳解

    Matplotlib實(shí)戰(zhàn)之堆疊面積圖繪制詳解

    堆疊面積圖和面積圖都是用于展示數(shù)據(jù)隨時間變化趨勢的統(tǒng)計(jì)圖表,但它們的特點(diǎn)有所不同,堆疊面積圖既能看到各數(shù)據(jù)系列的走勢,又能看到整體的規(guī)模,下面我們就來看看如何繪制堆疊面積圖吧
    2023-08-08
  • 使用Python實(shí)現(xiàn)簡單的學(xué)生成績管理系統(tǒng)

    使用Python實(shí)現(xiàn)簡單的學(xué)生成績管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了Python實(shí)現(xiàn)學(xué)生成績管理系統(tǒng),使用數(shù)據(jù)庫,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • django 實(shí)現(xiàn)手動存儲文件到model的FileField

    django 實(shí)現(xiàn)手動存儲文件到model的FileField

    這篇文章主要介紹了django 實(shí)現(xiàn)手動存儲文件到model的FileField,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-03-03
  • python爬取鏈家二手房的數(shù)據(jù)

    python爬取鏈家二手房的數(shù)據(jù)

    相信大家買房前都會在網(wǎng)上找找資料,看看行情,問問朋友,今天就用python帶大家扒一扒《鏈家二手房》的數(shù)據(jù)
    2021-05-05

最新評論