日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

Python高级编程:类和实例属性的查找顺序—mro查找

發(fā)布時間:2024/4/15 python 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python高级编程:类和实例属性的查找顺序—mro查找 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、?mro查找定義

如果多個類繼承父類,然后又被多個類繼承這種復(fù)雜的問題,可以使用mro方法

class D:pass class C(D):pass class B(D):pass class A(B,C):passprint(A.__mro__) 輸出結(jié)果: (<class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.D'>, <class 'object'>)

二、?mro查找應(yīng)用

自從Python2.3后使用C3 MRO算法,關(guān)于C3 MRO算法的詳情,參考The Python 2.3 Method Resolution Order?

MRO結(jié)果深度優(yōu)先搜索DFS?廣度優(yōu)先搜索BFS?
圖一A->B->D->C->E?A->B->C->D->E?
圖二A->B->D->C?A->B->C->D?

?

DFS:對應(yīng)圖2菱形繼承有問題。加入現(xiàn)在有一個方法get_value, C、D中存在get_value, A、B不存在get_value, 那么當(dāng)A調(diào)用get_value時,調(diào)用的就是D中的get_value方法。C中永遠(yuǎn)起不到重載D中方法的作用。因此DFS對菱形繼承有問題,在python2之后改為了廣度優(yōu)先算法。

BFS:圖2的菱形繼承問題解決了,但是圖1的繼承又出現(xiàn)了問題。?以圖1來說明,如果C和D中有一個同名的方法get_value, B和A中沒有g(shù)et_value方法,那么A調(diào)用get_value時,就會調(diào)用C中的方法,而實(shí)際上B和D應(yīng)該看成一個整體,在B中不存在就應(yīng)該去父類中搜索。因此在Python2.3后,提出了C3 MRO算法,解決了上面的兩個問題。

那么如何查看C3 MRO算法的搜索順序呢, 調(diào)用__mro__屬性

圖1: class D(object):passclass E(object):passclass B(D):passclass C(E):pass class A(B, C):passprint(A.__mro__) #MRO順序:A-->B-->D-->C-->E #結(jié)果:(<class '__main__.A'>, <class '__main__.B'>, <class '__main__.D'>, <class '__main__.C'>, <class '__main__.E'>, <class 'object'>) 圖2class D(object):passclass B(D):passclass C(D):pass class A(B, C):passprint(A.__mro__) # MRO順序:A-->B-->C-->D #結(jié)果:(<class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.D'>, <class 'object'>)

Python2.3到Python2.7:經(jīng)典類、新式類和平發(fā)展
因?yàn)橹暗腂FS存在較大的問題,所以從Python2.3開始新式類的MRO取而代之的是C3算法,我們可以知道C3算法肯定解決了單調(diào)性問題,和只能繼承無法重寫的問題。C3算法具體實(shí)現(xiàn)稍后講解。
MRO的C3算法順序如下圖:看起簡直是DFS和BFS的合體有木有。但是僅僅是看起來像而已

三、?C3算法原理

Python3到至今:新式類一統(tǒng)江湖
Python3開始就只存在新式類了,采用的MRO也依舊是C3算法。

我們要解決兩個問題:單調(diào)性問題和不能重寫的問題。
很容易發(fā)現(xiàn)要解決單調(diào)性,只要保證從根(A)到葉(object),從左到右的訪問順序即可。
那么對于只能繼承,不能重寫的問題呢?先分析這個問題的本質(zhì)原因,主要是因?yàn)橄仍L問了子類的父類導(dǎo)致的。那么怎么解決只能先訪問子類再訪問父類的問題呢?如果熟悉圖論的人應(yīng)該能馬上想到拓?fù)渑判?#xff0c;這里引用一下百科的的定義:
對一個有向無環(huán)圖(Directed Acyclic Graph簡稱DAG)G進(jìn)行拓?fù)渑判?#xff0c;是將G中所有頂點(diǎn)排成一個線性序列,使得圖中任意一對頂點(diǎn)u和v,若邊(u,v)∈E(G),則u在線性序列中出現(xiàn)在v之前。通常,這樣的線性序列稱為滿足拓?fù)浯涡?Topological Order)的序列,簡稱拓?fù)湫蛄小:唵蔚恼f,由某個集合上的一個偏序得到該集合上的一個全序,這個操作稱之為拓?fù)渑判颉?br /> 因?yàn)橥負(fù)渑判蚩隙ㄊ歉饺~(也不能說是葉了,因?yàn)橐呀?jīng)不是樹了),所以只要滿足從左到右,得到的拓?fù)渑判蚓褪墙Y(jié)果,關(guān)于拓?fù)渑判蛩惴?#xff0c;大學(xué)的數(shù)據(jù)結(jié)構(gòu)有教,這里不做講解,不懂的可以自行谷歌或者翻一下書,建議了解完算法再往下看。
那么模擬一下例子的拓?fù)渑判?#xff1a;首先找入度為0的點(diǎn),只有一個A,把A拿出來,把A相關(guān)的邊剪掉,再找下一個入度為0的點(diǎn),有兩個點(diǎn)(B,C),取最左原則,拿B,這是排序是AB,然后剪B相關(guān)的邊,這時候入度為0的點(diǎn)有E和C,取最左。這時候排序?yàn)锳BE,接著剪E相關(guān)的邊,這時只有一個點(diǎn)入度為0,那就是C,取C,順序?yàn)锳BEC。剪C的邊得到兩個入度為0的點(diǎn)(DF),取最左D,順序?yàn)锳BECD,然后剪D相關(guān)的邊,那么下一個入度為0的就是F,然后是object。那么最后的排序就為ABECDFobject。

對比一下 A.__mro__的結(jié)果(<class '__main__.A'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.D'>, <class '__main__.F'>, <type 'object'>)

參考文章:

MRO算法

4-6 類和實(shí)例屬性的查找順序----mro查找

總結(jié)

以上是生活随笔為你收集整理的Python高级编程:类和实例属性的查找顺序—mro查找的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。