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

python中的繼承機(jī)制super()函數(shù)詳解

 更新時(shí)間:2023年08月24日 14:14:43   作者:goodxin_ie  
這篇文章主要介紹了python中的繼承機(jī)制super()函數(shù)詳解,super 是用來(lái)解決多重繼承問(wèn)題的,直接用類(lèi)名調(diào)用父類(lèi)方法在使用單繼承的時(shí)候沒(méi)問(wèn)題,但是如果使用多繼承,會(huì)涉及到查找順序、重復(fù)調(diào)用等問(wèn)題,需要的朋友可以參考下

前言

super 是用來(lái)解決多重繼承問(wèn)題的,直接用類(lèi)名調(diào)用父類(lèi)方法在使用單繼承的時(shí)候沒(méi)問(wèn)題

但是如果使用多繼承,會(huì)涉及到查找順序(MRO)、重復(fù)調(diào)用(鉆石繼承)等種種問(wèn)題。

一、super用法

我們先簡(jiǎn)單的理解為super().xx相當(dāng)于調(diào)用了父類(lèi)中的xx方法(實(shí)際上在單繼承中是這樣,多繼承中有點(diǎn)區(qū)別)。

時(shí)候會(huì)看到像下面這樣直接調(diào)用父類(lèi)的一個(gè)方法:

class Base:
    def __init__(self):
        print('Base.__init__')
class A(Base):
    def __init__(self):
        Base.__init__(self)
        print('A.__init__')

盡管對(duì)于大部分代碼而言這么做沒(méi)什么問(wèn)題,但是在更復(fù)雜的涉及到多繼承的代碼中就有可能導(dǎo)致很奇怪的問(wèn)題發(fā)生。

比如,考慮如下的情況:

class Base:
    def __init__(self):
        print('Base.__init__')
class A(Base):
    def __init__(self):
        Base.__init__(self)
        print('A.__init__')
class B(Base):
    def __init__(self):
        Base.__init__(self)
        print('B.__init__')
class C(A,B):
    def __init__(self):
        A.__init__(self)
        B.__init__(self)
        print('C.__init__')
c = C()

如果你運(yùn)行這段代碼就會(huì)發(fā)現(xiàn) Base.__init__() 被調(diào)用兩次,如下所示:

 
Base.__init__
A.__init__
Base.__init__
B.__init__
C.__init__

但是當(dāng)我們?cè)诖a中換成使用 super() ,結(jié)果就很完美了:

class Base:
    def __init__(self):
        print('Base.__init__')
class A(Base):
    def __init__(self):
        super().__init__()
        print('A.__init__')
class B(Base):
    def __init__(self):
        super().__init__()
        print('B.__init__')
class C(A,B):
    def __init__(self):
        super().__init__()  # Only one call to super() here
        print('C.__init__')

運(yùn)行這個(gè)新版本后,你會(huì)發(fā)現(xiàn)每個(gè) __init__() 方法只會(huì)被調(diào)用一次了:

Base.__init__
B.__init__
A.__init__
C.__init__

二、super的本質(zhì)

先說(shuō)說(shuō)python中如何實(shí)現(xiàn)繼承---------對(duì)于你定義的每一個(gè)類(lèi),Python會(huì)計(jì)算出一個(gè)所謂的方法解析順序(MRO)列表。 這個(gè)MRO列表就是一個(gè)簡(jiǎn)單的所有基類(lèi)的線(xiàn)性順序表。為了實(shí)現(xiàn)繼承,Python會(huì)在MRO列表上從左到右開(kāi)始查找基類(lèi),直到找到第一個(gè)匹配這個(gè)屬性的類(lèi)為止。

而這個(gè)MRO列表的構(gòu)造是通過(guò)一個(gè)C3線(xiàn)性化算法來(lái)實(shí)現(xiàn)的。 我們不去深究這個(gè)算法的數(shù)學(xué)原理,它實(shí)際上就是合并所有父類(lèi)的MRO列表并遵循如下三條準(zhǔn)則:

  • 子類(lèi)會(huì)先于父類(lèi)被檢查
  • 多個(gè)父類(lèi)會(huì)根據(jù)它們?cè)诹斜碇械捻樞虮粰z查
  • 如果對(duì)下一個(gè)類(lèi)存在兩個(gè)合法的選擇,選擇第一個(gè)父類(lèi)

雖然名義上來(lái)說(shuō)super是用來(lái)調(diào)用父類(lèi)中的方法,但是super實(shí)際上是在MRO表中找到下一個(gè)匹配的類(lèi)。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. 通過(guò) cls 定位當(dāng)前 MRO 中的 index, 并返回 mro[index + 1]

我們來(lái)看一個(gè)例子,猜猜下面的輸出會(huì)是什么呢:

class A():
    def __init__(self):         
        print("Enter A")  
class B(A):
    def __init__(self):  
        print("Enter B")         
        super(B,self).__init__()  
        print("Leave B")       
class C(A):
    def __init__(self): 
        print("Enter C")            
        super(C,self).__init__()  
        print("Leave C")      
class D(B,C):
    def __init__(self): 
        print("Enter D")            
        super(D,self).__init__()
        print("Leave D")   
d = D()

直接看結(jié)果:

很多人將super簡(jiǎn)單的理解為調(diào)用父類(lèi)中的方法,可能認(rèn)為應(yīng)該是D調(diào)用B和C,由于B在左邊,按順序先調(diào)用B,B油調(diào)用A,完成之后輪到D調(diào)用C,C調(diào)用A.輸出變成下面這樣:

Enter D
Enter B
Enter A
Leave B
Enter C
Enter A
Leave C
Leave D

但是根據(jù)我們上面說(shuō)的super本質(zhì)知道super 和父類(lèi)其實(shí)沒(méi)有實(shí)質(zhì)關(guān)聯(lián),我們就不難理解為什么 enter B 下一句是 enter C 而不是 enter A了(如果認(rèn)為 super 代表“調(diào)用父類(lèi)的方法”,會(huì)想當(dāng)然的認(rèn)為下一句應(yīng)該是enter A)。流程如下,在 B 的 __init__ 函數(shù)中:

super(B,self).__init__() 首先獲取self.__class__.__mro__,但是這里的self是D的實(shí)例,而不是B的。

(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)

然后,通過(guò) B 來(lái)定位 MRO 中的 index,并找到下一個(gè)。

顯然 B 的下一個(gè)是 C。于是,我們調(diào)用 C 的 __init__,打出 enter C。

當(dāng)你使用super()函數(shù)時(shí),Python會(huì)在MRO列表上繼續(xù)搜索下一個(gè)類(lèi)。

只要每個(gè)重定義的方法統(tǒng)一使用super()并只調(diào)用它一次, 那么控制流最終會(huì)遍歷完整個(gè)MRO列表,每個(gè)方法也只會(huì)被調(diào)用一次。

到此這篇關(guān)于python中的繼承機(jī)制super()函數(shù)詳解的文章就介紹到這了,更多相關(guān)python繼承super()函數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python實(shí)現(xiàn)從常規(guī)文檔中提取圖片的方法詳解

    Python實(shí)現(xiàn)從常規(guī)文檔中提取圖片的方法詳解

    這篇文章主要為大家詳細(xì)介紹了如何使用Python實(shí)現(xiàn)從常規(guī)文檔(Word,PDF,Excel,HTML)中提取圖片的方法,有需要的小伙伴可以參考一下
    2025-03-03
  • 如何以Winsows Service方式運(yùn)行JupyterLab

    如何以Winsows Service方式運(yùn)行JupyterLab

    這篇文章主要介紹了如何以Winsows Service方式運(yùn)行JupyterLab的教程
    2020-08-08
  • Python正則獲取、過(guò)濾或者替換HTML標(biāo)簽的方法

    Python正則獲取、過(guò)濾或者替換HTML標(biāo)簽的方法

    這篇文章主要介紹了Python通過(guò)正則表達(dá)式獲取、過(guò)濾或者替換HTML標(biāo)簽的方法,感興趣的小伙伴們可以參考一下
    2016-01-01
  • python 重命名軸索引的方法

    python 重命名軸索引的方法

    今天小編就為大家分享一篇python 重命名軸索引的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-11-11
  • python爬蟲(chóng)中g(shù)et和post方法介紹以及cookie作用

    python爬蟲(chóng)中g(shù)et和post方法介紹以及cookie作用

    本篇文章通過(guò)爬取163郵箱實(shí)例介紹了python爬蟲(chóng)中g(shù)et和post方法介紹以及cookie作用,對(duì)此有興趣的朋友學(xué)習(xí)下。
    2018-02-02
  • python與caffe改變通道順序的方法

    python與caffe改變通道順序的方法

    今天小編就為大家分享一篇python與caffe改變通道順序的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • 解決Matplotlib中文顯示亂碼的完整教程

    解決Matplotlib中文顯示亂碼的完整教程

    在使用 Matplotlib 繪制圖表時(shí),很多開(kāi)發(fā)者都會(huì)遇到中文無(wú)法正常顯示的問(wèn)題,默認(rèn)情況下,Matplotlib 并不支持中文字符,需要手動(dòng)設(shè)置字體,這篇博客將教你如何解決 Matplotlib 繪圖顯示中文的常見(jiàn)問(wèn)題,確保中文字符能夠在圖表中正確顯示,需要的朋友可以參考下
    2024-12-12
  • 一文詳解如何在Python中使用Requests庫(kù)

    一文詳解如何在Python中使用Requests庫(kù)

    這篇文章主要介紹了如何在Python中使用Requests庫(kù)的相關(guān)資料,Requests庫(kù)是Python中常用的第三方庫(kù),用于簡(jiǎn)化HTTP請(qǐng)求的發(fā)送和響應(yīng)處理,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-02-02
  • Python 降級(jí)的兩種實(shí)現(xiàn)方法

    Python 降級(jí)的兩種實(shí)現(xiàn)方法

    本文主要介紹了Python 降級(jí)的兩種實(shí)現(xiàn)方法,幫助用戶(hù)在降級(jí)Python時(shí)不完全卸載,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-12-12
  • python 實(shí)現(xiàn)mysql自動(dòng)增刪分區(qū)的方法

    python 實(shí)現(xiàn)mysql自動(dòng)增刪分區(qū)的方法

    這篇文章主要介紹了python 實(shí)現(xiàn)mysql自動(dòng)增刪分區(qū)的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04

最新評(píng)論

邻水| 东台市| 安岳县| 镇巴县| 顺义区| 和政县| 湟源县| 九龙县| 徐闻县| 鹤山市| 甘洛县| 九龙坡区| 连江县| 兴义市| 兴宁市| 定陶县| 台前县| 西和县| 景德镇市| 石柱| 南汇区| 进贤县| 运城市| 任丘市| 濉溪县| 罗江县| 泸西县| 许昌市| 淮阳县| 柳河县| 丹阳市| 玛曲县| 句容市| 韩城市| 昌黎县| 太原市| 巴彦县| 祁东县| 西安市| 浠水县| 中山市|