最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

圖文詳解Python中最神秘的一個(gè)魔法函數(shù)

 更新時(shí)間:2021年12月23日 15:36:03   作者:晨xi的光  
Python進(jìn)階之路我覺(jué)得有兩個(gè)東西一定要了解,一個(gè)是魔法函數(shù),下面這篇文章主要給大家介紹了關(guān)于Python中最神秘的一個(gè)魔法函數(shù)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下

前言

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

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

本文主要關(guān)注的問(wèn)題有:(1)?missing()到底是何方神圣?(2)?missing()有什么特別之處?擅長(zhǎng)“大變活人”魔術(shù)?

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2、神出鬼沒(méi)的missing()

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

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

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

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

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

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

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

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

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

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

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

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

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

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

3、被施魔法的missing()

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

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

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

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

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

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

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

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

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

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

4、小結(jié)

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

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

這可能有一個(gè)很復(fù)雜(也可能是很簡(jiǎn)單)的解釋?zhuān)疚臅翰簧罹苛恕?/p>

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

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

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

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

本文揭示出了這個(gè)魔術(shù)方法的神秘之處,不知你讀后有何感想呢?

5、總結(jié)

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

相關(guān)文章

  • 關(guān)于python爬蟲(chóng)應(yīng)用urllib庫(kù)作用分析

    關(guān)于python爬蟲(chóng)應(yīng)用urllib庫(kù)作用分析

    這篇文章主要介紹了關(guān)于python爬蟲(chóng)應(yīng)用urllib庫(kù)作用分析,想要進(jìn)行python爬蟲(chóng)首先我們需要先將網(wǎng)頁(yè)上面的信息給獲取下來(lái),這就是utllib庫(kù)的作用,有需要的朋友可以借鑒參考下
    2021-09-09
  • 對(duì)pandas將dataframe中某列按照條件賦值的實(shí)例講解

    對(duì)pandas將dataframe中某列按照條件賦值的實(shí)例講解

    今天小編就為大家分享一篇對(duì)pandas將dataframe中某列按照條件賦值的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-11-11
  • python可變對(duì)象,不可變對(duì)象詳解

    python可變對(duì)象,不可變對(duì)象詳解

    這篇文章主要介紹了Python可變對(duì)象和不可變對(duì)象的相關(guān)資料,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2021-09-09
  • Python實(shí)現(xiàn)圖片指定位置加圖片水?。ǜ絇yinstaller打包exe)

    Python實(shí)現(xiàn)圖片指定位置加圖片水?。ǜ絇yinstaller打包exe)

    這篇文章主要介紹了Python實(shí)現(xiàn)圖片指定位置加圖片水印,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • 使用Python防止SQL注入攻擊的實(shí)現(xiàn)示例

    使用Python防止SQL注入攻擊的實(shí)現(xiàn)示例

    這篇文章主要介紹了使用Python防止SQL注入攻擊的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • Python練習(xí)-購(gòu)物單

    Python練習(xí)-購(gòu)物單

    這篇文章主要介紹了Python練習(xí)-購(gòu)物單,下文主要以舉例說(shuō)明從問(wèn)題描述開(kāi)始,以及解題思路展開(kāi)文章內(nèi)容,作為日常學(xué)習(xí)小練習(xí),需要的小伙伴可以參考一下
    2022-01-01
  • 深入了解Python?Flask框架之藍(lán)圖

    深入了解Python?Flask框架之藍(lán)圖

    這篇文章主要為大家介紹了Python?Flask框架之藍(lán)圖,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2021-12-12
  • Python中操作各種多媒體,視頻、音頻到圖片的代碼詳解

    Python中操作各種多媒體,視頻、音頻到圖片的代碼詳解

    這篇文章主要介紹了Python玩轉(zhuǎn)各種多媒體,視頻、音頻到圖片,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-06-06
  • 基于python的ini配置文件操作工具類(lèi)

    基于python的ini配置文件操作工具類(lèi)

    這篇文章主要為大家詳細(xì)介紹了基于python的ini配置文件操作工具類(lèi),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-04-04
  • Python獲取指定網(wǎng)段正在使用的IP

    Python獲取指定網(wǎng)段正在使用的IP

    這篇文章主要介紹了Python獲取指定網(wǎng)段正在使用的IP的示例代碼,幫助大家更好的利用python進(jìn)行測(cè)試,感興趣的朋友可以了解下
    2020-12-12

最新評(píng)論

衡东县| 济宁市| 龙井市| 北宁市| 论坛| 博白县| 浦江县| 榆林市| 新余市| 昌宁县| 桦南县| 海林市| 宁津县| 尼玛县| 印江| 盈江县| 南宫市| 宜都市| 永平县| 黄陵县| 金溪县| 沙坪坝区| 偏关县| 遂川县| 全南县| 吉安县| 绥宁县| 许昌市| 会理县| 甘洛县| 云安县| 江永县| 禹城市| 汾阳市| 民和| 乌兰察布市| 荃湾区| 克什克腾旗| 涿州市| 桃园县| 剑河县|