Python多继承C3算法解析

Python多继承MROO
Python2.1采用经典类,采用深度优先算法进行分析。
Python2.2.采用深度优先算法和广度优先算法,引入了新类别。
DFS算法和C3算法用于Python2.3后的版本中。
Python2中的经典类
classA(object): pass
Python3新型类型
classA: pass
C3算法
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).
这是维基百科全书的定义。下图为多继承关系图:

那么这里的mro分析顺序是什么呢?单纯看图片很难得到答案。
C3线性算法的推导过程如下:
假设C继承自父B1...Bn,类C的分析列表公式如下:

该公式表明,C的解析列表是通过对其所有父类的解析列表及其父类的merge获得的。
相关推荐:Python视频教程
merge操作分为以下几个步骤:
1.选择merge中的第一个列表作为当前列表K。
2.令h = head(K), 如果h没有出现在任何其他列表的tail(除了列表中的第一个元素,其余的称为tail)中,则将其添加到类C的线性列表中,并从merge中删除所有列表,然后重复步骤2。
3.否则,将K设置为merge的下一个列表,重复2中的操作。
4.如果merge的所有类别都被删除,输出类别将成功创建;如果找不到下一个h,则输出C类抛出异常。
推导过程
我们用上面的图片来推导mro的分析顺序。
上图转换为python代码如下:
将Python代码转换为Python代码
O=object classA(O):pass classB(O):pass classC(O):pass classD(O):pass classE(O):pass classK1(A,B,C):pass ClassK2(D,B,E):pass classk3(D,A):pass classZ(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(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算法的过程与我们推导的结果相同。
