python中使用多繼承,會涉及到查找順序(MRO)、重復調用(鑽石繼承,也叫菱形繼承問題)等
MRO
MRO即method resolution order,用於判斷子類調用的屬性來自於哪個父類。在Python2.3之前,MRO是基於深度優先算法的,自2.3開始使用C3算法,定義類時需要繼承object,這樣的類稱為新式類,否則為舊式類
從圖中可以看出,舊式類查找屬性時是深度優先搜索,新式類則是廣度優先搜索
C3算法最早被提出是用於Lisp的,應用在Python中是為了解決原來基於深度優先搜索算法不滿足本地優先級,和單調性的問題。
- 本地優先級:指聲明時父類的順序,比如C(A,B),如果訪問C類對象屬性時,應該根據聲明順序,優先查找A類,然后再查找B類。
- 單調性:如果在C的解析順序中,A排在B的前面,那么在C的所有子類里,也必須滿足這個順序
示例
看下面的例子
class X(object): def f(self): print 'x' class A(X): def f(self): print 'a' def extral(self): print 'extral a' class B(X): def f(self): print 'b' def extral(self): print 'extral b' class C(A, B, X): def f(self): super(C, self).f() print 'c' print C.mro() c = C() c.f() c.extral()
根據廣度搜索原則最先搜索到A,所以結果很明顯,如下所示
類C沒有extral函數,調用的是子類的該函數。這種類的部分行為由父類來提供的行為,叫做抽象超類.