我们知道python中的类与类之间是可以相互继承的。在继承关系中,子类自动拥有父类中除了私有属性之外的其他所有内容。python中支持多继承,也就是说一个类可以有多个父类。但是在多继承中,存在这样一个问题:当两个父类中出现重名方法的时候,如何处理他们的继承关系,即MRO(method resolution order)方法解析顺序问题。
Python2中的MRO
在python2中存在两种类:
- 经典类:在python2.2之前。一直使用的是经典类。经典类的根如果什么都不写,表示继承XXX。
- 新式类:在python2.2之后出现了新式类。新式类的特点是基类的根是object
Python3中的MRO
- python3中使用的都是新式类。如果基类谁都不继承,那么这个类会默认继承object。
本文只讲述Python3新式类的MRO
计算公式L[C(B)] = C + merge(L[B],B) = C + L[B]
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 M:
pass
class N(M):
pass
class P(E, A):
pass
class X:
pass
class Q(P,N,X):
pass
class G(Q, F):
pass
class H(G, F):
pass
L(H) = H + L(G) + L(F) + GF => H + GQPFDBECANMX + FDBECA + GF => HGQPFDBECANMX
L(G) = G + L(G) + L(F) + QF => GQPFDBECANMX
L(Q) = Q + L(P) + L(N) + L(X) + PNX => QPECANMX
L(X) = X => X
L(P) = P + L(E) + L(A) + EA => PECA
L(N) = N + L(M) + M => NM
L(M) = M => M
L(F) = F + L(D) + L(E) + DE => FDBECA
L(E) = E + L(C) + L(A) + CA => ECA
L(D) = D + L(B) + L(C) + BC => DBCA
L(C) = C + L(A) + A => CA
L(B) = B + L(A) + A => BA
L(A) = A => A
求H的MRO
设求MRO的算法是L
加法:merge(), 拿第一项的第一位和 后面每项的除了第一位比较. 如果没有出现, 则该位元素算出
如果出现了. 此时开始下一项的第一位继续和后面每一项的除了第一位比较:
用头和后面身体比较
上面的是手工算的MRO,其实在python中可以使用类名.mro(H.__mro__
)的方式直接输出对应类的MRO。
(<class '__main__.H'>, <class '__main__.G'>, <class '__main__.Q'>, <class '__main__.P'>,
<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>,
<class '__main__.C'>, <class '__main__.A'>, <class '__main__.N'>, <class '__main__.M'>,
<class '__main__.X'>, <class 'object'>)
网友评论