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

Python中類(lèi)的mro與繼承關(guān)系詳解(二)

 更新時(shí)間:2022年07月28日 08:48:38   作者:??宿者朽命???  
這篇文章主要介紹了Python中類(lèi)的mro與繼承關(guān)系詳解,上一篇我們已經(jīng)通過(guò)mro相關(guān)資料介紹了mro繼承關(guān)系的基礎(chǔ)內(nèi)容,這片緊接著上一篇文章展開(kāi)詳細(xì)內(nèi)容,需要的朋友可以參考一下

前言

版本:

  • windows 10.0
  • python 3.8

多重繼承

Python數(shù)字比較與類(lèi)結(jié)構(gòu)中有簡(jiǎn)略提到類(lèi),且在Python中類(lèi)的mro與繼承關(guān)系詳解稍有解釋繼承關(guān)系,用到一個(gè)基類(lèi)Animal如下:

class Animal:
    property_ = '能夠思考'

    def __init__(self, name, age, value):
        self.name_ = name
        self.age_ = age
        self.val_ = val

再定義Action活動(dòng)作為另一個(gè)基類(lèi):

class Action:

    def __init__(self, action, val):
        self.action_ = action
        self.val_ = val
  • 現(xiàn)在需定義一個(gè)Dog類(lèi),不僅是動(dòng)物,還能夠跑,可以來(lái)繼承上面兩個(gè)類(lèi)來(lái)定義:
class Dog(Animal, Action):

    def __init__(self, name, age, action, val):
        Animal.__init__(self, name, age, val+1)
        Action.__init__(self, action, val)

dog = Dog('大福', 8, '跑', 78)
print(dog.__dict__)
# {'name_': '大福', 'age_': 8, 'val_': 78, 'action_': '跑'}

發(fā)現(xiàn)打印出的實(shí)例屬性,好像字典的鍵值更新,先初始化Animal時(shí),val傳入的值為79,而后被更新為78,這里為什么不能像繼承單個(gè)類(lèi)一樣直接用super方法代替呢。

上一篇有提到mro解析順序,可進(jìn)行嘗試,不重寫(xiě)__init__方法,發(fā)現(xiàn)Dog類(lèi)只能傳入三個(gè)參數(shù),且都為Animal類(lèi)的參數(shù),因?yàn)槔^承的兩個(gè)父類(lèi)都有該方法,優(yōu)先繼承左邊的父類(lèi)方法,如果想都繼承可以考慮這樣的形式,然而會(huì)提高后續(xù)維護(hù)的困難性。

可以將最左邊的父類(lèi)改成super方式:

class Dog(Animal, Action):

    def __init__(self, name, age, action, val):
        super().__init__(name, age, val+1)
        Action.__init__(self, action, val)

mro解析順序,與上面所述一致:

Dog.mro()
# [__main__.Dog, __main__.Animal, __main__.Action, object]
  • 祖孫類(lèi)

如再進(jìn)行繼承,視Dog為父類(lèi),其Animal,Action都為祖父類(lèi),定義一個(gè)Pet類(lèi):

class Pet(Dog):
    pass
pet = Pet('大福', 8, '跑', 78)

傳入?yún)?shù),和實(shí)例化的對(duì)象跟Dog一樣,如果需要改寫(xiě)某個(gè)方法,可以參照之前的方法進(jìn)行改寫(xiě),另外若在保留原方法的邏輯上進(jìn)行補(bǔ)充則用super方法。

Pet類(lèi)的mro:

Pet.mro()
# [__main__.Pet, __main__.Dog, __main__.Animal, __main__.Action, object]

思考片刻

通過(guò)上面的繼承及對(duì)應(yīng)的mro解析順序,可以思考以下通過(guò)多重繼承類(lèi)后,輸出的x屬性值為多少:

class Alpha:
    def __init__(self, val):
        self.x = val

class Beta(Alpha):
    pass

class Gamma:
    def __init__(self, val):
        self.x = val + 1
class Omega(Gamma):
    def __init__(self, val):
        super().__init__(val + 1)
class Kappa(Beta, Omega):
    pass
k = Kappa(1)
print(k.x)

如果腦內(nèi)沒(méi)有一個(gè)mro解析順序圖,這里準(zhǔn)備了:

[__main__.Kappa, __main__.Beta, __main__.Alpha, __main__.Omega, __main__.Gamma, object]

這里或許會(huì)有疑問(wèn),Beta后面不是Omega嗎?怎么到Alpha了,可以先看下Omega,繼承Gamma,而GammaAlpha并不是同源的,類(lèi)似于Dog類(lèi)的繼承,那么優(yōu)先就會(huì)使用Alpha的__init__方法,所以在傳入?yún)?shù)值1的時(shí)候,僅運(yùn)行了Alpha內(nèi)的self.x = val,屬性x被賦值成1,在最后print輸出即為1,打印結(jié)果檢查:

print(k.x)
# 1

若把Gamma類(lèi)改成繼承Alpha類(lèi),再次猜測(cè)print(k.x)的值為多少?

class Alpha:
    def __init__(self, val):
        self.x = val

class Beta(Alpha):
    pass

class Gamma(Alpha):
    def __init__(self, val):
        self.x = val + 1

class Omega(Gamma):
    def __init__(self, val):
        super().__init__(val + 1)

class Kappa(Beta, Omega):
    pass

k = Kappa(1)
print(k.x)

查看mro解析順序:

[__main__.Kappa, __main__.Beta, __main__.Omega, __main__.Gamma, __main__.Alpha, object]

此時(shí)發(fā)現(xiàn)Alpha解析優(yōu)先級(jí)排在最后,BetaOmega可以看做是BetaGamma的優(yōu)先級(jí)比較,因?yàn)?code>Omega繼承Gamma,且重寫(xiě)了__init__方法,所以當(dāng)傳入?yún)?shù)時(shí)會(huì)對(duì)Gamma類(lèi)的屬性進(jìn)行賦值,雖然Beta類(lèi)直接繼承Alpha,但Gamma類(lèi)也直接繼承,所以Alpha解析順序需要排在Gamma后面,從而當(dāng)Kappa類(lèi)傳入?yún)?shù)時(shí),經(jīng)過(guò)Omega的super加1,傳入到Gamma處時(shí)為:self.x = val + 1中的val為2,輸出的k.x的值即為3,查看打印結(jié)果:

print(k.x)
# 3

總結(jié)

通過(guò)連續(xù)兩篇對(duì)類(lèi)繼承及mro解析順序的說(shuō)明,理解類(lèi)在多重繼承中的變化,無(wú)論繼承多少遍,總歸要回歸本心,但也不能胡亂繼承,有條理的,有意義的繼承,才能讓自己乃至他人更好理解當(dāng)下寫(xiě)出的類(lèi)。

到此這篇關(guān)于Python中類(lèi)的mro與繼承關(guān)系詳解的文章就介紹到這了,更多相關(guān)Python mro內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

营山县| 鹤庆县| 两当县| 察雅县| 芦溪县| 宜川县| 庄河市| 乌什县| 东源县| 凭祥市| 永寿县| 托里县| 漾濞| 河曲县| 同心县| 辽源市| 连城县| 乌兰察布市| 清远市| 普安县| 遂宁市| 凯里市| 静宁县| 定日县| 东乡| 万宁市| 澜沧| 定兴县| 乐至县| 海原县| 安义县| 龙胜| 平原县| 宝丰县| 汾阳市| 佛教| 龙海市| 鹤岗市| 万盛区| 吐鲁番市| 永嘉县|