Python中類得mro與繼承關系詳解(二)

目錄

前言

版本:

  • windows 10.0
  • python 3.8

多重繼承

Python數字比較與類結構中有簡略提到類,且在Python中類得mro與繼承關系詳解稍有解釋繼承關系,用到一個基類Animal如下:

class Animal:    property_ = '能夠思考'    def __init__(self, name, age, value):        self.name_ = name        self.age_ = age        self.val_ = val

再定義Action活動作為另一個基類:

class Action:    def __init__(self, action, val):        self.action_ = action        self.val_ = val
  • 現在需定義一個Dog類,不僅是動物,還能夠跑,可以來繼承上面兩個類來定義:
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_': '跑'}

發現打印出得實例屬性,好像字典得鍵值更新,先初始化Animal時,val傳入得值為79,而后被更新為78,這里為什么不能像繼承單個類一樣直接用super方法代替呢。

上一篇有提到mro解析順序,可進行嘗試,不重寫__init__方法,發現Dog類只能傳入三個參數,且都為Animal類得參數,因為繼承得兩個父類都有該方法,優先繼承左邊得父類方法,如果想都繼承可以考慮這樣得形式,然而會提高后續維護得困難性。

可以將最左邊得父類改成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]
  • 祖孫類

如再進行繼承,視Dog為父類,其Animal,Action都為祖父類,定義一個Pet類:

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

傳入參數,和實例化得對象跟Dog一樣,如果需要改寫某個方法,可以參照之前得方法進行改寫,另外若在保留原方法得邏輯上進行補充則用super方法。

Pet類得mro:

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

思考片刻

通過上面得繼承及對應得mro解析順序,可以思考以下通過多重繼承類后,輸出得x屬性值為多少:

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

如果腦內沒有一個mro解析順序圖,這里準備了:

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

這里或許會有疑問,Beta后面不是Omega嗎?怎么到Alpha了,可以先看下Omega,繼承Gamma,而GammaAlpha并不是同源得,類似于Dog類得繼承,那么優先就會使用Alpha得__init__方法,所以在傳入參數值1得時候,僅運行了Alpha內得self.x = val,屬性x被賦值成1,在最后print輸出即為1,打印結果檢查:

print(k.x)# 1

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

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

查看mro解析順序:

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

此時發現Alpha解析優先級排在最后,BetaOmega可以看做是BetaGamma得優先級比較,因為Omega繼承Gamma,且重寫了__init__方法,所以當傳入參數時會對Gamma類得屬性進行賦值,雖然Beta類直接繼承Alpha,但Gamma類也直接繼承,所以Alpha解析順序需要排在Gamma后面,從而當Kappa類傳入參數時,經過Omega得super加1,傳入到Gamma處時為:self.x = val + 1中得val為2,輸出得k.x得值即為3,查看打印結果:

print(k.x)# 3

總結

通過連續兩篇對類繼承及mro解析順序得說明,理解類在多重繼承中得變化,無論繼承多少遍,總歸要回歸本心,但也不能胡亂繼承,有條理得,有意義得繼承,才能讓自己乃至他人更好理解當下寫出得類。

到此這篇關于Python中類得mro與繼承關系詳解得內容就介紹到這了,更多相關Python mro內容請搜索之家以前得內容或繼續瀏覽下面得相關內容希望大家以后多多支持之家!

聲明:所有內容來自互聯網搜索結果,不保證100%準確性,僅供參考。如若本站內容侵犯了原著者的合法權益,可聯系我們進行處理。
發表評論
更多 網友評論1 條評論)
暫無評論

返回頂部

主站蜘蛛池模板: 成人毛片一区二区| 最近高清日本免费| 国产精品免费综合一区视频| 亚洲一区二区日韩欧美gif| 色五五月五月开| 日本一区二区高清| 北条麻妃一区二区三区av高清| mm131美女做爽爽爱视频| 欧美高清性色生活片免费观看| 国产精品久久久久影视青草| 久久国产精品无码一区二区三区| 老湿机香蕉久久久久久| 女神校花乳环调教| 亚洲国产夜色在线观看| 韩国三级hd中文字幕| 干妞网在线观看| 亚洲欧美日韩一区在线观看| 黑人与中国女一级毛片不卡| 性满足久久久久久久久| 亚洲欧美校园春色| 黄色网站在线免费观看| 成人免费毛片观看| 亚洲欧洲第一页| 香港经典a毛片免费观看看| 希崎杰西卡一二三区中文字幕| 亚洲日韩欧美一区二区三区在线| 麻豆福利在线观看| 奶特别大的三级日本电影| 亚洲国产精品福利片在线观看| 要灬要灬再深点受不了好舒服 | 国产精品久线观看视频| 丰满少妇人妻久久久久久| 男人操女人视频免费| 国产欧美精品午夜在线播放| 三级视频网站在线观看| 欧美国产在线视频| 四虎影院在线播放视频| 7777奇米四色| 手机在线看片不卡中文字幕| 亚洲欧美综合国产精品一区| 里番库全彩本子彩色h可知子|