在程序中出現了多個類的繼承並且出現了菱形繼承,而且又要用到super,知道MRO就顯得極爲重要,咱們使用C3算法來計算MRO面試
下面經過例子來解釋:算法
class A: pass class B(A): pass class C(A): pass class D(B,C): pass class E(C,A): pass class F(D,E): pass class N: pass class O: pass class M(N,O): pass class G(E,M): pass class H(G,F): pass
咱們來計算上述代碼的MRO函數
1.首先把繼承樹圖畫出來spa
是這樣子的(不太好看,湊合一下)code
2.假設C3算法是一個函數式,繼承表明相加,而後把函數式寫出來,很簡單,看着繼承樹圖寫,不過順序要與代碼中繼承的順序相同blog
L(A) = A繼承
L(B) = B + L(A)it
L(C) = C + L(A)class
L(D) = D + L(B) + L(C)object
L(E) = E + L(C) + L(A)
L(F) = F + L(D) + L(E)
L(M) = M + L(N) + L(O)
L(G) = G + L(E) + L(M)
L(H) = H + L(G) + L(F)
3.函數式寫出來了,下來咱們進行化簡
L(A) = A
L(B) = B + L(A) = BA
L(C) = C + L(A) = CA
L(D) = D + L(B) + L(C) = D + BA + CA =DBCA
L(E) = E + L(C) + L(A) = E + CA + A = ECA
L(F) = F + L(D) + L(E) = F + DBCA + ECA = FDBECA
L(M) = M + L(N) + L(O) = M + N + O =MNO
L(G) = G + L(E) + L(M) = G + ECA + MNO = GECAMNO
L(H) = H + L(G) + L(F) = H + GECAMNO + FDBECA = HGFDBECAMNO
函數式中的+表明的是merge(),merge規則:
1. 若是第一個序列的第一個元素,是後續序列的第一個元素,或者再也不後續序列中再次出現,則將這個元素合併到最終的方法解析順序序列中,並從當前操做的所有序列中刪除。
2. 若是不符合,則跳過此元素,查找下一個列表的第一個元素,重複1的判斷規則
最後咱們能夠來驗證
print(H.__mro__)
發現順序與咱們算的順序相同,只不事後邊多了個class object,由於咱們全部的類都要繼承obj,因此也不足爲奇
咱們計算MRO就是要爲super作鋪墊,因此咱們來看一道面試題
class Init(object): def __init__(self,v): print("init") self.val = v class Add2(Init): def __init__(self,val): print("Add2") super(Add2,self).__init__(val) print(self.val) self.val += 2 class Mult(Init): def __init__(self,val): print("Mult") super(Mult, self).__init__(val) self.val *= 5 class HaHa(Init): def __init__(self,val): print("HaHa") super(HaHa,self).__init__(val) self.val /= 5 class Pro(Add2,Mult,HaHa): pass class Incr(Pro): def __init__(self,val): super(Incr,self).__init__(val) self.val += 1 p = Incr(5) print(p.val)
大體看一眼,發現出現了多個繼承,還涉及到了super的用法,按照方法一步一步來
1.畫繼承樹圖
2.而後算出MRO:Incr,Pro,Add,Mult,Haha,Init,(Object)
3.super是訪問MRO中下一個類的內容,秉持着這個原則咱們進行稍加分析,這道題只不過是幾個super的疊用,答案不難算出來