在Python2.1中,採用了經典類,使用深度優先算法解析。
Python2.2中,引入了新式類,使用深度優先算法和廣度優先算法。
在Python2.3之後的版本中,經典類和新式類共存,使用了DFS算法和C3算法。
Python2中的經典類python
class A(object): pass
Python3的新式類算法
class A: pass
In computing, the C3 superclass linearization is an algorithm used primarily to obtain the order in which methods should be inherited (the "linearization") in the presence of multiple inheritance, and is often termed Method Resolution Order (MRO).
這是維基百科中的定義,下面這張圖是一張多繼承的關係圖:
3d
那麼這裏的mro解析順序是如何的呢?單純看圖很可貴出答案。
C3線性算法的推導過程以下:
假設類C繼承自父類B1,...Bn,類C的解析列表公式以下:
這個公式代表C的解析列表是經過對其全部父類的解析列表及其父類一塊兒merge獲得的。
merge操做分爲以下幾個步驟:code
咱們用上面的那張圖試一下推導出mro的解析順序。
上面那張圖轉換爲python代碼以下:
轉換成Python代碼blog
O = object class A(O): pass class B(O): pass class C(O): pass class D(O): pass class E(O): pass class K1(A, B, C): pass class K2(D, B, E): pass class K3(D, A): pass class Z(K1, K2, K3): pass print(Z.mro())
L(K1) = K1 + merge(L[A],L[B],L[C],(A,B,C)) = K1 + merge(L[A,O],L[B,O],L[C,O],(A,B,C)) = [K1,A] + merge(L[O],L[B,O],L[C,O],(B,C)) = [K1,A,B] + merge(L[O],L[O],L[C,O],(C)) = [K1,A,B,C] + merge(L[O],L[O],L[O]) = [K1,A,B,C,O] L(K2) = [K2,D,B,E,O] L(K3) = [K3,D,A,O] 以上是K1,K2,K3的解析順序 下面是Z的推導過程 L(Z) = Z + merge(L(K1)+L(K2)+L[K3],(K1,K2,K3)) = Z + merge(L[K1,A,B,C,O]+L(K2,D,B,E,O)+L(K3,D,A,O),(K1,K2,K3)) = [Z,K1] + merge(L[A,B,C,O]+L(K2,D,B,E,O)+L(K3,D,A,O),(K2,K3)) = [Z,K1,K2] + merge(L[A,B,C,O]+L(D,B,E,O)+L(K3,D,A,O),(K3)) = [Z,K1,K2,K3] + merge(L[A,B,C,O]+L(D,B,E,O)+L(D,A,O)) = [Z,K1,K2,K3,D] + merge(L[A,B,C,O]+L(B,E,O)+L(A,O)) = [Z,K1,K2,K3,D,A] + merge(L[B,C,O]+L(B,E,O)+L(O)) = [Z,K1,K2,K3,D,A,B] + merge(L[C,O]+L(E,O)+L(O)) = [Z,K1,K2,K3,D,A,B,C] + merge(L[O]+L(E,O)+L(O)) = [Z,K1,K2,K3,D,A,B,C,E,O]
咱們得出的最終答案爲:Z的解析順序:Z->K1->K2->K3->D->A->B->C->E->O
爲了驗證答案,咱們在python中運行繼承
print(Z.mro())
結果以下圖片
[<class '__main__.Z'>, <class '__main__.K1'>, <class '__main__.K2'>, <class '__main__.K3'>, <class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.E'>, <class 'object'>]
和咱們推導的結果相同,這就是C3算法的流程。ip