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

歡迎訪問 生活随笔!

生活随笔

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

python

Python 之 super MRO (没有遇到过适用场景)

發(fā)布時(shí)間:2025/4/14 python 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python 之 super MRO (没有遇到过适用场景) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

WOW!!!

這里wow的是真尼瑪繞且沒看完,

好困吶,貼上網(wǎng)址,等自己英文好一點(diǎn)再看(https://rhettinger.wordpress.com/2011/05/26/super-considered-super/),,,,

自己的理解:

先上例子:

例1:

class A(object):def __init__(self):print "enter A"print "leave A"class B(object):def __init__(self):print "enter B"print "leave B"class C(A):def __init__(self):print "enter C"super(C, self).__init__()print "leave C"class D(A):def __init__(self):print "enter D"super(D, self).__init__()print "leave D"class E(B, C):def __init__(self):print "enter E"B.__init__(self)C.__init__(self)print "leave E"class F(E, D):def __init__(self):print "enter F"E.__init__(self)D.__init__(self)print "leave F"

輸出:

enter Fenter Eenter Bleave Benter Center Denter Aleave Aleave Dleave Cleave Eenter Denter Aleave Aleave Dleave F

按我們對(duì)super的理解,從圖中可以看出,在調(diào)用類C的初始化函數(shù)時(shí),應(yīng)該是調(diào)用類A的初始化函數(shù),但事實(shí)上卻調(diào)用了類D的初始化函數(shù)。好一個(gè)詭異的問題!并且類A和類D的初始化函數(shù)被重復(fù)調(diào)用了2次

這是為什么呢?

super不是簡(jiǎn)單地調(diào)用所謂基類的方法,而是調(diào)用MRO中的下一個(gè)類的方法,也就是類似于next的方法。

mro中記錄了一個(gè)類的所有基類的類類型序列。查看mro的記錄,發(fā)覺包含7個(gè)元素,7個(gè)類名分別為:F E B C D A object

從而說明了為什么在C.__init__中使用super(C, self).__init__()會(huì)調(diào)用類D的初始化函數(shù)了。

不要一說到 super 就想到父類!super 指的是 MRO 中的下一個(gè)類!

MRO & super

Method resolution order是python用來(lái)解析方法調(diào)用順序的。MRO對(duì)于多重繼承中方法調(diào)用異常重要。python中有一個(gè)內(nèi)建函數(shù)和MRO密切相關(guān)——super。具體實(shí)現(xiàn)方式,有興趣可以以后看看。

在 MRO 中,基類永遠(yuǎn)出現(xiàn)在派生類后面,如果有多個(gè)基類,基類的相對(duì)順序保持不變。

super做了什么?

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

兩個(gè)參數(shù) cls 和 inst 分別做了兩件事:
1. inst 負(fù)責(zé)生成 MRO 的 list
2. 通過 cls 定位當(dāng)前 MRO 中的 index, 并返回 mro[index + 1]

super的作用是什么呢?

按名字繼承的話,如果子類的父類發(fā)生變化時(shí),必須要全部替換名字,比較麻煩;

  

?

如果沒有復(fù)雜的繼承結(jié)構(gòu),super 作用不大。

例2:(沒太看懂這貨)

class A(object):def __init__(self):print "enter A"super(A, self).__init__() # new 寄幾繼承寄幾是什么鬼?print "leave A"class B(object):def __init__(self):print "enter B"super(B, self).__init__() # newprint "leave B"class C(A):def __init__(self):print "enter C"super(C, self).__init__()print "leave C"class D(A):def __init__(self):print "enter D"super(D, self).__init__()print "leave D"class E(B, C):def __init__(self):print "enter E"super(E, self).__init__() # changeprint "leave E"class F(E, D):def __init__(self):print "enter F"super(F, self).__init__() # changeprint "leave F"

輸出:

enter Fenter Eenter Benter Center Denter Aleave Aleave Dleave Cleave Bleave Eleave F

明顯地,F的初始化不僅完成了所有的父類的調(diào)用,而且保證了每一個(gè)父類的初始化函數(shù)只調(diào)用一次。

?

那么,總結(jié):

1. super并不是一個(gè)函數(shù),是一個(gè)類名,形如super(B, self)事實(shí)上調(diào)用了super類的初始化函數(shù),?產(chǎn)生了一個(gè)super對(duì)象;

2. super類的初始化函數(shù)并沒有做什么特殊的操作,只是簡(jiǎn)單記錄了類類型和具體實(shí)例;

3. super(B, self).func的調(diào)用并不是用于調(diào)用當(dāng)前類的父類的func函數(shù);

4. Python的多繼承類是通過mro的方式來(lái)保證各個(gè)父類的函數(shù)被逐一調(diào)用,而且保證每個(gè)父類函數(shù)只調(diào)用一次(如果每個(gè)類都使用super);

?

    如果類被設(shè)計(jì)成使用了super,那么所有子類也必須要調(diào)用super,否則直接調(diào)用會(huì)出現(xiàn)重復(fù)調(diào)用的問題

?

5. 混用super類和非綁定的函數(shù)是一個(gè)危險(xiǎn)行為,這可能導(dǎo)致應(yīng)該調(diào)用的父類函數(shù)沒有調(diào)用或者一個(gè)父類函數(shù)被調(diào)用多次。(保持一致性。要不全部用類名調(diào)用父類,要不就全部用 super,不要一半一半。)

?

參考:

http://www.cnblogs.com/lovemo1314/archive/2011/05/03/2035005.html(super)

http://blog.csdn.net/rommi/article/details/51058360(MRO)

http://blog.csdn.net/seizef/article/details/5310107(super & MRO)?

??

轉(zhuǎn)載于:https://www.cnblogs.com/pannyvan/p/6135190.html

總結(jié)

以上是生活随笔為你收集整理的Python 之 super MRO (没有遇到过适用场景)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

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