Python3中的MRO C3算法

作者: 飞跑的蛤蟆 | 来源:发表于2019-03-10 21:43 被阅读4次

我们知道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'>)

相关文章

网友评论

    本文标题:Python3中的MRO C3算法

    本文链接:https://www.haomeiwen.com/subject/orvppqtx.html