《Django By Example》

Python3中的MRO C3算法

2019-03-10  本文已影响4人  飞跑的蛤蟆

我们知道python中的类与类之间是可以相互继承的。在继承关系中,子类自动拥有父类中除了私有属性之外的其他所有内容。python中支持多继承,也就是说一个类可以有多个父类。但是在多继承中,存在这样一个问题:当两个父类中出现重名方法的时候,如何处理他们的继承关系,即MRO(method resolution order)方法解析顺序问题。

Python2中的MRO

在python2中存在两种类:

Python3中的MRO

本文只讲述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'>)
上一篇 下一篇

猜你喜欢

热点阅读