MRO的計算(C3算法及應用)

在程序中出現了多個類的繼承並且出現了菱形繼承,而且又要用到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的疊用,答案不難算出來

相關文章
相關標籤/搜索