python的继承体系mro详解

来源:互联网 发布:程序员很难吗 编辑:程序博客网 时间:2024/05/16 19:12

本文为阅读python官方文档之mro详解,所得的一些笔记。

文档地址:https://www.python.org/download/releases/2.3/mro/


python在2.2之后引入了新式类,即继承自object的类。在2.3引入了全新的mro来对继承的顺序等进行管理。

在此之前,python按照从左到右的继承顺序,进行深度优先遍历,得出继承树的顺序。


引入mro后,按照C3算法, 进行线性化。


C3算法:

首先介绍一些记号,C1C2...CN表示一系列类[C1,C2,...CN  ]

head = C1  tail = C2...CN,同时,C1+C2...CN = C1C2...CN

假设C继承自B1B2...BN,那么C的mro线性数组为L[C],规则为:C的线性mro数组为C加上C的父类的mro数组和父类的集合的归并。

符号表示为:L[C(B1B2...BN)] = C + merge(L[B1],L[B2],....L[BN],B1B2...BN)

如果C是object类,没有父类,则L[C] = C

归并的算法表示如下:取第一个列表的head,如L[B1][0],如果head没有在之后任一的列表中的tail中出现,那么把它加在C的mro数组中,然后将它从所有的列表中移除。

重复该操作,直到找不到满足条件的head。

例子1:

class A(object):pass

class B(object):pass

class C(A,B):pass

class D(B,A):pass

class E(C,D):pass

在该例中,A.mro() = A,O  ;  B.mro() = B,O; C.mro() = C,A,B,O; D.mro() = D,B,A,O;

E.mro() = E + merge(CABO + DBAO,CD) = EC + MERGE(ABO,DBAO,D) = ECD + MERGE(ABO,BAO)

可以发现,找不到满足条件的head,所以python会报错:typeError


例子2:

>>> O = object>>> class F(O): pass>>> class E(O): pass>>> class D(O): pass>>> class C(D,F): pass>>> class B(D,E): pass>>> class A(B,C): pass

L[O] = O

L[F] = FO

L[E] = EO

L[D] = DO

L[C] = C + MERGE(DO,FO,DF) = CD + MERGE(O,FO,F) = CDFO

L[B] = B + MERGE(DO,EO,DE) = BD + MERGE(O,EO,E) = BDEO
L[A] = A + MERGE(BDEO,CDFO,BC) = AB + MERGE(DEO,CDFO,C) = ABC + MERGE(DEO,DFO) = ABCD + MERGE(EO,FO) = ABCDEFO


例子3:

将例子2中B的继承顺序改变一下

>>> O = object>>> class F(O): pass>>> class E(O): pass>>> class D(O): pass>>> class C(D,F): pass>>> class B(E,D): pass>>> class A(B,C): pass

L[O] = O

L[F] = FO

L[E] = EO

L[D] = DO

L[C] = C + MERGE(DO,FO,DF) = CD + MERGE(O,FO,F) = CDFO

L[B] = B + MERGE(DO,EO,ED) = BE + MERGE(DO,O,D) = BEDO
L[A] = A + MERGE(BEDO,CDFO,BC) = AB + MERGE(EDO,CDFO,C) = ABE + MERGE(DO,CDFO,C) = ABEC + MERGE(DO,DFO) = ABECDFO


例子4:

>>> F=type('Food',(),{'remember2buy':'spam'})>>> E=type('Eggs',(F,),{'remember2buy':'eggs'})>>> G=type('GoodFood',(F,E),{})
L[F] = FO

L[E] = EFO

L[G] = G + MERGE(FO,EFO,FE)结果是报错,发生冲突,无法得到满足条件的head。


python新式类中mro的计算过程大致如此,更详细细节可参见链接:https://www.python.org/download/releases/2.3/mro/















0 0
原创粉丝点击