亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Python的MRO

系統(tǒng) 1792 0

Python的MRO即Method Resolution Order(方法解析順序),也就是在Python中的類的繼承順序是怎樣的。在Python2.3之前,MRO的實(shí)現(xiàn)是基于DFS的,而在Python2.3以后MRO的實(shí)現(xiàn)是基于C3算法(我這里兩種算法的具體實(shí)現(xiàn)都不詳述)。C3算法最早被提出是用于Lisp的,應(yīng)用在Python中是為了解決原來基于深度優(yōu)先搜索算法不滿足本地優(yōu)先級(jí),和單調(diào)性的問題。本地優(yōu)先級(jí):指聲明時(shí)父類的順序,比如C(A,B),如果訪問C類對(duì)象屬性時(shí),應(yīng)該根據(jù)聲明順序,優(yōu)先查找A類,然后再查找B類。單調(diào)性:如果在C的解析順序中,A排在B的前面,那么在C的所有子類里,也必須滿足這個(gè)順序。

?

總的來說,一個(gè)類的 MRO 列表就是合并所有父類的 MRO 列表,并遵循以下三條原則:

子類永遠(yuǎn)在父類前面

如果有多個(gè)父類,會(huì)根據(jù)它們?cè)诹斜碇械捻樞虮粰z查

如果對(duì)下一個(gè)類存在兩個(gè)合法的選擇,選擇第一個(gè)父類

?

下面我用圖解的形式來表現(xiàn)三條原則并計(jì)算出MRO(只是說這種方式可以手算出MRO,而不是說這是C3算法的具體實(shí)現(xiàn)方式):

首先看以下代碼

            
              class F:
    pass

class E:
    pass

class D:
    pass

class B(D,E):
    pass

class C(D,F):
    pass

class A(B,C):
    pass
            
          

然后我們構(gòu)建一個(gè)繼承順序圖(圖是指數(shù)據(jù)結(jié)構(gòu)中的圖,不是圖片的圖,當(dāng)然,無所謂了..@_@|||||..?)

即讓子類用箭頭指向父類,逐層排列成類似下圖這種

Python的MRO_第1張圖片

遇到多繼承則按代碼中繼承列表的順序從左往右寫。如果有多個(gè)子類繼承了同一個(gè)父類,那么這個(gè)父類則放在它 能夠出現(xiàn)的所有位置中最左的位置(注意:如下圖中那樣,D既可以放在B的左上方,又可以放在C的左上方,這種情況下,我們選擇放在B的左上方,因?yàn)檫@樣D在其所在層更加靠左) ,然后讓這些子類指向它,就像下圖中類D那樣。

Python的MRO_第2張圖片

然后依據(jù)代碼就可以形成上面的這個(gè)繼承順序圖。(在python中,任何類默認(rèn)都是繼承自object類的,所以讓最上層的D、E、F指向object。當(dāng)然,你也可以選擇在畫圖的時(shí)候?qū),B,C等等所有類都畫一個(gè)指向object的箭頭,但隨著以下方法的進(jìn)行,其實(shí)這兩種畫法結(jié)果是一樣的。)

?

接下來,我們就開始算出相應(yīng)的MRO。即需遵循圖里面的廣度優(yōu)先原則進(jìn)行遍歷(在廣度優(yōu)先原則的前提下又優(yōu)先遍歷左邊的):

首先尋找整個(gè)圖中入度為0的,也就是A,那么A也就成為MRO中的第一個(gè)。

然后我們?nèi)サ魣D中的A節(jié)點(diǎn)以及與A相關(guān)的連線,再尋找入度為0的點(diǎn),這時(shí)有B和C兩個(gè)節(jié)點(diǎn),我們選擇最左邊的點(diǎn)即B。選完左邊的B點(diǎn)后,再選右邊的C點(diǎn),這樣B和C也就跟著進(jìn)入了MRO序列,現(xiàn)在MRO序列為{A,B,C}。(注意每次層次遍歷一定要把那一層選完才能選下一層,不能在沒有選C之前跳到選E)

然后去掉B和C以及與它們相關(guān)的連線,這時(shí)候入度為0的也就是D、E、F了,依次選擇,使D、E、F進(jìn)入MRO序列。

最后也就使得object進(jìn)入MRO序列。

?

以上的MRO序列也就是{ABCDEFobject}

使用 類名.mro()可以查閱其MRO表:

?

?

最后說一下super

一般都會(huì)說,在類中用super()可以取父類的成員變量和成員方法

更具體地講是super(cls, inst)?,它獲得的是類cls 在實(shí)例inst的 MRO 列表中的下一個(gè)類。(也就說是實(shí)例或者說對(duì)象I有一個(gè)MRO列表,這個(gè)列表中有類C,而我們獲取的就是類C的后面的那個(gè)類)

工作原型為

            
              def super(cls, inst):
    mro = inst.__class__.mro()
    return mro[mro.index(cls) + 1]

            
          

這里需要注意的是inst處是一個(gè)實(shí)例,而不是一個(gè)未實(shí)例化的類。

故而可以在類里super(B,self).方法? ? ?或者

在類外x=C() 然后super(B,x).方法

?

轉(zhuǎn)載請(qǐng)標(biāo)明出處,原文地址:https://blog.csdn.net/come_from_pluto


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 青青青青青青久久久免费观看 | 99热最新网址获取 | 欧美freesex呦交| 888米奇色狠狠俺去啦 | 国产尤物福利视频在线观看 | 欧美日韩一二三区 | 91大神在线精品视频一区 | 一区二区三区四区在线视频 | 狠狠色伊人亚洲综合成人 | 久久综合精品国产一区二区三区 | 豆国产96在线 | 亚洲 | 一级香蕉免费毛片 | 久久久久久国产视频 | 狠狠操狠狠干 | 久久久日韩精品国产成人 | 天天干天天玩 | 欧美成成人免费 | 中文字幕一区二区三区在线观看 | 99热这里只有精品4 99热这里只有精品5 | 中文视频在线 | 一级毛片一级毛片一级毛片 | 国产一级内谢a级高清毛片 国产一级片毛片 | 特级生活片 | 新久草在线视频 | 99在线视频免费观看 | 青青青青啪视频在线观看 | 国内精品久久久久久影院网站小说 | 日韩一区二区在线视频 | 四虎永久在线精品 | 亚洲精品欧美精品中文字幕 | 爱爱小视频在线观看网站 | 国产成人免费网站在线观看 | 国产一级精品视频 | 日本免费成人网 | 综合色久 | 96国产xxxx | 久久一区二区精品 | 欧美日韩大片 | 男人天堂网在线视频 | 6080欧美一区二区三区四区 | 妞干网中文字幕 |