mro即method resolution order,方法呼叫順序。python是一門支援多繼承的語言,當乙個子類(該子類繼承了兩個父類)的物件執行方法a時,該子類沒有定義方法a,而兩個父類都定義了方法a,那麼應該執行哪個父類的方法a?這個時候就需要mro來制定執行順序。
看個例子
classf(
):pass
class
a(f)
:pass
class
b(f)
:pass
class
c(a, b)
:pass
print
(c.mro(
))
輸出結果
[
<
class
'__main__.c'
>
,<
class
'__main__.a'
>
,<
class
'__main__.b'
>
,<
class
'__main__.f'
>
,<
class
'object'
>
]
mro的計算過程
使用o記號來表示某個類的mro,假如類m的父類為[m1, m2…mn],
o(m) = [m] + [o(m1), o(m2)…o(mn), [m1], [m2]…[mn]]
加號之後是一串列表,其中每個列表的第乙個元素為該列表頭,列表中的剩餘元素為該列表的尾。從一串列表中的最左邊開始,取該列表的頭,假如該列表的頭沒有出現在其他列表的尾中,那麼就可以把這個頭提到列表外,作為次一級優先順序的類與之前的合併。同時把該類從所有的列表中刪除。一直持續到列表為空。如果最後列表不為空,說明這是個錯誤的繼承,python中會給出異常提示。
還是上邊的例子
o(f) = [f]
o(a) = [a] + [o(f)] = [a] + [f] = [a, f]
o(b) = [b] + [o(f)] = [b] + [f] = [b, f]
o[c] = [c] + [o(a), o(b), [a], [b] ]
= [c] + [[a, f], [b, f], [a], [b] ]
= [c, a] + [[f], [b, f], [b] ]
= [c,a,b] + [[f], [f] ]
= [c, a, b, f]
當c的例項呼叫某個方法時,就按照該順序進行查詢,直到找到實現了該方法的類。
classf(
):deffoo
(self)
:print
('i am f fool'
)class
a(f)
:pass
class
b(f)
:def
foo(self)
:print
('i am b fool'
)class
c(a, b)
:passc()
.foo(
)
輸出結果
i am b fool
在沿著mro查詢的過程中,c和a都沒有實現該方法,查詢到b的時候,發現b實現了該方法,就執行了b的foo方法。
classf(
):deffoo
(self)
:print
('i am f fool'
)class
a(f)
:def
foo(self)
:print
('i am a fool'
)super
(a, self)
.foo(
)class
b(f)
:def
foo(self)
:print
('i am b fool'
)class
c(a, b)
:passc()
.foo(
)
執行結果
i am a fool
i am b fool
在查詢foo的方法的過程中,發現a實現了該方法,列印了 i am a fool,由於a的foo方法呼叫的父類的foo方法,在mro中可以看到a之後的類為b,於是下一步再執行b類中實現的foo方法。 Python中的多繼承
python和c 一樣,支援多繼承。概念雖然容易,但是困難的工作是如果子類呼叫乙個自身沒有定義的屬性,它是按照何種順序去到父類尋找呢,尤其是眾多父類中有多個都包含該同名屬性。class p1 object deffoo self print p1 foo class p2 object deffoo...
python中的多繼承
一 介紹 python同樣有限的支援多繼承形式。多繼承的類定義形如下例 class derivedclassname base1,base2,base3 需要注意圓括號中父類的順序,若是父類中有相同的方法名,而在子類使用時未指定,python從左至右搜尋 即方法在子類中未找到時,從左到右查詢父類中是...
Python中的多繼承
coding utf8 1.多繼承 子類有多個父類 class human def init self,self.defp self print 這是human的方法 class person def init self,name self.name name defp self print 這是p...