久久精品五月,日韩不卡视频在线观看,国产精品videossex久久发布 ,久久av综合

站長資訊網
最全最豐富的資訊網站

Python魔法函數學習之__missing__

本篇文章給大家帶來了關于python的相關知識,其中主要介紹了“__missing__()”函數的相關問題,下面我們就一起來看一下這個魔法函數,希望對大家有幫助。

Python魔法函數學習之__missing__

推薦學習:python學習教程

1、有點價值的__missing__()

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

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

Python魔法函數學習之__missing__

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

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

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

如果用原生的 dict,并不太好實現,但是,Python 提供了一個非常好用的擴展類collections.defaultdict

Python魔法函數學習之__missing__

如圖所示,當取不存在的 key 時,沒有再報 KeyError,而是默認存入到字典中。

為什么 defaultdict 可以做到這一點呢?

原因是 defaultdict 在繼承了內置類型 dict 之后,還定義了一個 __missing__() 方法,當 __getitem__取不存在的值時,它就會調用入參中傳入的工廠函數(上例是調用 list(),創建空列表)。

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

Python魔法函數學習之__missing__

簡而言之,__missing__()的主要作用就是由__getitem__在缺失 key 時調用,從而避免出現 KeyError。

另外一個典型的使用例子是collections.Counter,它也是 dict 的子類,在取未被統計的 key 時,返回計數 0:

Python魔法函數學習之__missing__

2、神出鬼沒的__missing__()

由上可知,__missing__()在__getitem__()取不到值時會被調用,但是,我不經意間還發現了一個細節:__getitem__()在取不到值時,并不一定會調用__missing__()。

這是因為它并非內置類型的必要屬性,并沒有在字典基類中被預先定義。

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

使用 dir() 查看,發現確實不存在該屬性:

Python魔法函數學習之__missing__

如果從 dict 的父類即 object 中查看,也會發現同樣的結果。

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

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

Python魔法函數學習之__missing__

出處:https://docs.python.org/3/reference/datamodel.html?highlight=__missing__#object.__missing__

也就是說,理論上 object 類中會預定義__missing__,其文檔證明了這一點,然而實際上它并沒有被定義!文檔與現實出現了偏差!

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

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

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

Python魔法函數學習之__missing__

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

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

3、被施魔法的__missing__()

__missing__() 的神奇之處,除了它本身會變“魔術”之外,它還需要一股強大的“魔法”才能驅動。

在上篇文章中,我發現原生的魔術方法間相互獨立,它們在 C 語言界面可能有相同的核心邏輯,但是在 Python 語言界面,卻并不存在著調用關系:

Python魔法函數學習之__missing__

魔術方法的這種“老死不相往來”的表現,違背了一般的代碼復用原則,也是導致內置類型的子類會出現某些奇怪表現的原因。

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

但是,對于特例__missing__(),Python 卻不得不妥協,不得不付出這種代價!

__missing__() 是魔術方法的“二等公民”,它沒有獨立的調用入口,只能被動地由 __getitem__() 調用,即__missing__() 依賴于__getitem__()。

不同于那些“一等公民”,例如 __init__()、__enter__()、__len__()、__eq__() 等等,它們要么是在對象生命周期或執行過程的某個節點被觸發,要么由某個內置函數或操作符觸發,這些都是相對獨立的事件,無所依賴。

__missing__() 依賴于__getitem__(),才能實現方法調用;而 __getitem__() 也要依賴 __missing__(),才能實現完整功能。

為了實現這一點,__getitem__()在解釋器代碼中開了個后門,從 C 語言界面折返回 Python 界面,去調用那個名為“__missing__”的特定方法。

Python魔法函數學習之__missing__

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

4、小結

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

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

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

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

為了讓字典類型有更強大的表現(或者說讓__getitem__()作出 get() 那樣的表現),Python 讓字典的子類可以定義__missing__(),供__getitem__()查找調用。

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

Python 為了維持魔術方法的獨立性,不惜煞費苦心地引入了 UserString、UserList、UserDict 這些派生類,但是對于 __missing__(),它卻選擇了妥協。

推薦學習:python教程

贊(0)
分享到: 更多 (0)
?
網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
久久精品五月,日韩不卡视频在线观看,国产精品videossex久久发布 ,久久av综合
国产一区二区三区久久| 98精品久久久久久久| 黄色亚洲在线| 亚洲国产一区二区三区在线播放| 99久久亚洲精品| 国产尤物精品| 国产亚洲精品v| 首页欧美精品中文字幕| 亚洲欧美网站在线观看| 亚洲欧美日韩国产| 日韩精品一级中文字幕精品视频免费观看| 国产精品免费看| 日韩一区精品字幕| 日韩有吗在线观看| 91精品麻豆| 精品女同一区二区三区在线观看| 国产成人精品一区二区三区在线| 日本不卡免费高清视频在线| 欧美肉体xxxx裸体137大胆| 国产高清一区| 亚洲欧美日韩精品一区二区| 日韩手机在线| 你懂的网址国产 欧美| 伊人久久视频| 五月精品视频| 天堂久久av| 国产伦理一区| 人在线成免费视频| 亚洲欧美日韩综合国产aⅴ| 日韩二区三区四区| 精品国产精品久久一区免费式 | 亚洲二区免费| 先锋影音久久久| 日韩国产欧美视频| 久久精品毛片| aa国产精品| 欧美日本二区| 久久久成人网| 日韩精品一区第一页| 麻豆久久一区| 黄色亚洲免费| 国产极品模特精品一二| 久久在线免费| 欧美一区精品| 色婷婷狠狠五月综合天色拍| 免费黄网站欧美| 久久香蕉精品香蕉| 欧美日韩日本国产亚洲在线| 欧美日韩18| 久久精品影视| 久久国内精品| 婷婷综合激情| 久久免费福利| 国产婷婷精品| 国产在线不卡一区二区三区| 亚洲一区二区三区四区五区午夜 | 国产亚洲毛片| 国产精品99精品一区二区三区∴| 香蕉久久精品| 国产精品白丝久久av网站| 久久在线免费| 国产精品v亚洲精品v日韩精品| 欧美不卡高清| 欧美国产亚洲精品| 亚洲一区国产| 日韩综合精品| 国产日韩免费| 免播放器亚洲| 午夜av不卡| 国产欧美日韩精品一区二区三区 | 国产亚洲久久| 一本色道精品久久一区二区三区| 另类小说一区二区三区| 在线午夜精品| 最近高清中文在线字幕在线观看1| 亚洲一区二区三区中文字幕在线观看| 国内精品伊人| 国产亚洲精品美女久久久久久久久久| 国产精品三上| 色一区二区三区| 国产精品亚洲二区| 喷白浆一区二区| 99国产精品一区二区| 国产精品九九| 日本少妇精品亚洲第一区| 婷婷综合激情| 欧美成人基地| 久久av网站| 天堂av一区| 日韩午夜在线| 91精品久久久久久久久久不卡| 久久久91麻豆精品国产一区| 日韩一二三区在线观看| 麻豆9191精品国产| 伊人久久大香线蕉av不卡| 日韩综合一区| 免费看一区二区三区| 日韩1区2区日韩1区2区| 综合一区av| 亚洲欧美高清| 日韩一级网站| 亚洲成人日韩| 99久久精品网| 日韩中文在线电影| 神马久久午夜| 福利一区在线| 精品国产不卡一区二区| 麻豆成人av在线| 久久不见久久见国语| 久久精品超碰| 国产毛片精品| 国产欧美久久一区二区三区| 日本不卡一二三区黄网| 蜜臀av性久久久久蜜臀aⅴ流畅| 午夜久久影院| 美女网站一区| 一区二区视频欧美| 99热精品在线观看| 欧美大黑bbbbbbbbb在线| 欧美亚洲国产激情| 激情久久五月| 亚洲精品va| 在线看片不卡| 亚洲欧洲日本mm| 玖玖玖国产精品| 综合一区av| 国产日韩欧美一区在线| 欧美成人一二区| 国产传媒在线| 偷拍精品精品一区二区三区| 久久三级视频| 一本一道久久a久久精品蜜桃| 中文日韩欧美| 美国三级日本三级久久99| 日韩一区二区三区高清在线观看| 91麻豆精品激情在线观看最新| 国产欧美一级| 国内不卡的一区二区三区中文字幕| 黑人精品一区| 91久久午夜| 日韩精品1区2区3区| 国产精品久久久网站| 精品视频久久| 999国产精品999久久久久久| 9色国产精品| 69堂免费精品视频在线播放| 麻豆视频观看网址久久| 国产乱码午夜在线视频| 一区二区三区四区日本视频| 亚洲先锋成人| 一区二区精彩视频| 国产精品免费99久久久| 福利精品一区| 日韩一级网站| 欧美日韩亚洲一区三区| 福利一区二区| 在线亚洲自拍| 国产欧美激情| 亚洲不卡系列| 视频一区中文字幕国产| 青青草91久久久久久久久| 成人国产精品久久| 亚洲激情五月| 日韩精品免费一区二区夜夜嗨| 国产精品久久久免费| 精品亚洲美女网站| 蜜臀久久久久久久| 欧美黄色一区| 久久国产中文字幕| 蜜臀国产一区二区三区在线播放| 国产精品超碰| 欧美日韩激情| 国产视频一区二| 色婷婷狠狠五月综合天色拍| 亚洲精品自拍| 日韩欧美1区| 亚洲18在线| 日韩久久精品网| 亚洲精品观看| 久久人人88| 国产精品一区二区av日韩在线| 日韩精品欧美激情一区二区| 日韩精品亚洲一区二区三区免费| 久久久一本精品| 日韩一区二区三区精品| 日本在线高清| 国产色噜噜噜91在线精品| 久久精品青草| 国产精品v日韩精品v欧美精品网站 | 在线精品观看| 国产一区二区三区精品在线观看| 久久久久国产精品一区二区| 日韩高清不卡在线| 99视频精品全部免费在线视频| 欧美日韩一区二区国产| 亚洲国产成人精品女人| 久久亚洲黄色| 亚洲精品日韩久久| 久久蜜桃精品| 美腿丝袜亚洲一区|