Python多重繼承的使用小結(jié)
繼承是面向?qū)ο缶幊讨械囊粋€特性,允許類繼承另一個類的屬性和方法。在 Python 中,你可以實現(xiàn)不同類型的繼承,比如單繼承、多繼承和多層繼承。本章詳細(xì)介紹了多重繼承。
什么是多重繼承?
多重繼承是一種繼承方式,其中單個類可以繼承多個父類的屬性和方法。當(dāng)你想把多個類的功能整合到一個類里時,這可以用。下圖展示了多重繼承 −

多重繼承的例子
在下面的例子中,子類繼承了父類和母類 -
class Father:
def skill1(self):
print("Father's skill: Gardening")
class Mother:
def skill2(self):
print("Mother's skill: Cooking")
class Child(Father, Mother):
pass
c = Child()
c.skill1()
c.skill2()上述代碼的輸出為−
Father's skill: Gardening
Mother's skill: Cooking
解釋:在這個例子中,子類可以同時訪問其父類的 skill1() 和 skill2() 方法。當(dāng)我們創(chuàng)建 Child 實例并調(diào)用 skill1() 時,它執(zhí)行的是 Father 類的方法。同樣,當(dāng)我們調(diào)用 skill2() 時,它執(zhí)行的是母類的方法。
但是,如果兩個父類都有同名的方法,會發(fā)生什么?誰會被處決?這就是方法分辨率次序(MRO)發(fā)揮作用的地方。
多重繼承的方法解析順序
如果同名方法在多個父類中定義,Python 會遵循特定的順序來決定執(zhí)行哪個方法。該命令被稱為方法解析令(MRO)。該階數(shù)由C3線性化算法(也稱為MRO)確定。MRO命令如下所示。
- 首先,Python 在子類中查找方法。
- 如果找不到,它會按列表的順序搜索父類。
- 直到找到方法或搜索所有類為止。
多重繼承最核心的問題是:當(dāng)多個父類有同名方法時,子類調(diào)用該方法會優(yōu)先執(zhí)行哪個父類的?Python 通過MRO(Method Resolution Order,方法解析順序) 來解決這個問題,遵循 “從左到右、深度優(yōu)先” 的原則(Python3 中是 C3 算法,本質(zhì)是優(yōu)化后的深度優(yōu)先)。
你可以用mro()方法或__mro__屬性檢查對象的MRO。例如−
print(Child.mro()) Output: [<class '__main__.Child'>, <class '__main__.Father'>, <class '__main__.Mother'>, <class 'object'>]
示例
在以下示例中,Child 類繼承了 Father 和 Mother 類的 skill() 方法,但調(diào)用的是 mother's 方法。
class Father:
def skill(self):
print("Father's skill: Gardening")
class Mother:
def skill(self):
print("Mother's skill: Cooking")
class Child(Father, Mother):
pass
c = Child()
c.skill()解釋:當(dāng)技能方法在子類實例c中被調(diào)用時,它首先會在子類中查找該方法。由于子類沒有技能方法,它會按父類排序(父類,然后是母類)搜索父類,并執(zhí)行第一個找到的。
上述代碼的輸出為−
Father's skill: Gardening
在多重繼承中使用 super()
super() 函數(shù)被子類用于調(diào)用父類的方法。如果你在多重繼承情況下的方法中使用 super(),它會嚴(yán)格按照 MRO 命令來決定調(diào)用哪個方法。
示例
在這個例子中,我們有一個包含四個類的類層級結(jié)構(gòu):A、B、C 和 D。類 D 繼承自 B 和 C,證明了多重繼承。
class A:
def show(self):
print("Class A")
class B(A):
def show(self):
print("Class B")
super().show()
class C(A):
def show(self):
print("Class C")
super().show()
class D(B, C):
def show(self):
print("Class D")
super().show()
d = D()
d.show()上述代碼的輸出為−
Class D
Class B
Class C
Class A
解釋:D類的MRO為[D, B, C, A, 對象]。這意味著當(dāng)某個方法在D實例上被調(diào)用時,Python會先在D中尋找該方法,然后是B,再是C,最后是A。因此,“D類”、“B類”、“C類”和“A類”將按該順序印刷。
多重繼承中的鉆石問題
鉆石問題是多重繼承中常見的問題。當(dāng)兩個父類繼承同一個基類,而子類繼承兩個父類時,就會出現(xiàn)這種情況。下圖展示了這個場景:

鉆石問題導(dǎo)致在繼承基類時,該調(diào)用哪個方法產(chǎn)生混淆。Python 通過遵循我們之前討論過的方法解析順序(mro)來解決這個問題。讓我們看看鉆石問題的例子 −
示例
下面的代碼演示了鉆石問題以及Python如何通過MRO解決 −
class A:
def show(self):
print("Class A")
class B(A):
def show(self):
print("Class B")
class C(A):
def show(self):
print("Class C")
class D(B, C):
pass
d = D()
d.show()上述代碼的輸出為−
Class B
解釋:D類的MRO命令為[D, B, C, A]。所以,當(dāng)調(diào)用 d.show() 時,它首先在類 D 里查找,但那里沒有 show 函數(shù),于是它會去 class B,找到 show 函數(shù)并執(zhí)行它。
多重繼承的坑與最佳實踐
1. 避免的問題
- 鉆石繼承(菱形繼承):多個父類最終繼承自同一個基類,可能導(dǎo)致重復(fù)調(diào)用或?qū)傩詻_突(Python3 的 C3 算法已解決,但仍需謹(jǐn)慎)。
- 代碼可讀性差:過多父類會讓代碼邏輯混亂,難以維護(hù)。
2. 最佳實踐
- 盡量少用多重繼承:能用單一繼承 + 組合 / 接口實現(xiàn)的,就不用多重繼承。
- 使用 Mixin 模式:將通用功能封裝成 Mixin 類(僅包含方法,無屬性),作為輔助繼承,主邏輯仍用單一繼承。
# Mixin類:僅提供通用功能
class SwimMixin:
def swim(self):
print("會游泳")
# 主父類
class Person:
def eat(self):
print("會吃飯")
# 子類:主繼承Person,輔助繼承SwimMixin
class Student(Person, SwimMixin):
pass
stu = Student()
stu.eat() # 輸出:會吃飯
stu.swim() # 輸出:會游泳多重繼承的利弊
多重繼承有若干優(yōu)缺點 -
| 優(yōu)點 | 缺點 |
|---|---|
| 提升代碼模塊化和可復(fù)用性。 | 增加了復(fù)雜度,可能導(dǎo)致模糊性。 |
| 允許將多個類別的功能組合在一起。 | 這可能導(dǎo)致鉆石問題。 |
| 可以創(chuàng)建復(fù)雜的現(xiàn)實關(guān)系 | 調(diào)試和維護(hù)更難。 |
多重繼承是一種面向?qū)ο缶幊痰母拍?,其中來自多個父類的方法可以被子類繼承。我們討論了 Python 如何利用方法解析順序(MRO)處理多重繼承,以及如何使用 super() 函數(shù)。鉆石問題在多重繼承中很常見,但 Python 通過 MRO 解決了這個問題。多重繼承的主要缺點是讓職業(yè)層級結(jié)構(gòu)更復(fù)雜且更難理解。
結(jié)論
- Python 支持多重繼承,子類可繼承多個父類的屬性和方法,寫法為
class 子類(父類1, 父類2, ...)。 - 同名方法的執(zhí)行順序遵循 MRO 規(guī)則,可通過
__mro__查看,默認(rèn)優(yōu)先執(zhí)行左側(cè)父類的方法。 - 實際開發(fā)中應(yīng)盡量少用多重繼承,推薦 Mixin 模式(輔助功能 + 主繼承),保證代碼可讀性和可維護(hù)性。
到此這篇關(guān)于Python多重繼承的使用小結(jié)的文章就介紹到這了,更多相關(guān)Python多重繼承內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
利用python解決mysql視圖導(dǎo)入導(dǎo)出依賴的問題
這篇文章主要給大家介紹了關(guān)于利用python解決mysql視圖導(dǎo)入導(dǎo)出依賴的問題,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用python具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-12-12
10 行Python 代碼實現(xiàn) AI 目標(biāo)檢測技術(shù)【推薦】
這篇文章主要介紹了10 行Python 代碼,實現(xiàn) AI 目標(biāo)檢測技術(shù),看完了代碼,我們在一起聊聊目標(biāo)檢測背后的技術(shù)背景,并解讀這10行Python代碼的由來和實現(xiàn)原理。感興趣的朋友跟隨小編一起看看吧2019-06-06
python之如何使用openpyxl設(shè)置單元格樣式
這篇文章主要介紹了python之如何使用openpyxl設(shè)置單元格樣式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-06-06
零基礎(chǔ)寫python爬蟲之urllib2中的兩個重要概念:Openers和Handlers
文章首先介紹了urllib2的2個方法,然后詳細(xì)介紹了urllib2中的2個重要概念Openers和Handlers的相關(guān)知識,希望能對大家有所幫助2014-11-11
python通過cookie模擬已登錄狀態(tài)的初步研究
對于那些需要在登錄環(huán)境下進(jìn)行的爬蟲操作,模擬登陸或偽裝已登錄狀態(tài)是一個剛性需求。這篇文章主要介紹了python通過cookie模擬已登錄狀態(tài)的相關(guān)資料,需要的朋友可以參考下2016-11-11

