最近在學習python的多重繼承。
先來了解下多重繼承的概念,所謂多重繼承,是指python的類可以有兩個以上父類,也即有類a,類b,類c,c同時繼承類a與類b,此時c中可以使用a與b中的屬性與方法。那麼問題來了,如果a與b中具有相同名字的方法,這個時候python怎麼呼叫的會是哪個方法呢?
舉個例子:
class a(object):
def __init__(self):
pass
def foo(self):
print 'a foo'
class b(object):
def __init__(self):
pass
def foo(self):
print 'b foo'
class c(a,b):
def __init__(self):
pass
testc = c()
testc.foo()
實際上列印出來的資訊是 a foo,這就說明了呼叫的是a中的方法。其實在python2.2之後,多繼承中基類的尋找順序是一種廣度優先演算法,稱之為c3的演算法(後續部落格我會簡單介紹下c3演算法)。而python2.2之前,使用的是深度優先演算法來尋找基類方法。在類c的繼承關係中,按照廣度優先演算法,則會先找到靠近c的基類a,在a中找到foo方法之後,就直接返回了,因此即使後面的基類b中也有foo方法,但是這裡不會引用它。
更加清晰的多繼承例子:
class(, , , , , )a(object):
deffoo(self):
'a foo
'class
b(object):
deffoo(self):
'b foo
'def
bar(self):
'b bar
'class
c1(a,b):
pass
class
c2(a,b):
defbar(self):
'c2-bar
'class
d(c1,c2):
pass
if__name__ =='
__main__':
print d.__mro__ #只有新式類有__mro__屬性,告訴查詢順序是怎樣的
d=d()
d.foo()
d.bar()
執行的結果為:
a foo (實際上搜尋順序為d=>c1=>a)
c2 bar(實際上搜尋順序為d=>c1=>c2)
可以看到,foo找到的是a類中的方法,bar找到的是c2中的方法。
其實新式類的搜尋方法是採用了「廣度優先」的方式去查詢屬性。
只有新式類有__mro__屬性,該屬性標記了python繼承層次中父類查詢的順序,python多重繼承機制中就是按照__mro__的順序進行查詢,一旦找到對應屬性,則查詢馬上返回。
經過上面的__mro__輸出可以發現,d類的繼承查詢路徑為:d=>c1=>c2=>a=>b=>object,通過該查詢路徑,foo方法將會呼叫a的foo方法,、bar方法將呼叫c2的方法,通過實際實驗呼叫,檢視輸出內容確實與__mro__順序一樣。
新式類 經典類與多繼承
python3所有的類都繼承自object類 新式類 1.python3中,所有類都是新式類 2.python2中主動繼承object類 經典類 python2中,不繼承object類 多繼承 class a pass class b a pass b繼承a class c a pass c繼承a ...
python044 (多繼承04 新式類和經典類)
object是python為所有物件提供的基類,提供有一些內建的屬性和方法,可以使用dir函式檢視 在python3.x中定義類時,如果沒有指定父類,會預設使用object作為該類的基類 python3.x中定義的類都是新式類 在python2.x中定義類時,如果沒有指定父類,則不會以object作...
繼承 新式類 經典類
目錄 二 利用繼承減少 冗餘 三 繼承的菱形問題 四 如何重用父親的屬性和方法 經典類 python2中有繼承類 新式類 python3中都是新式類 是一種新建類方式,繼承了乙個類,類中的屬性和方法就在子類中 父類 基類 子類 派生類 新式類 只要繼承了object類,在python3中,預設繼承o...