MRO的计算(C3算法及应用)

在程序中出现了多个类的继承而且出现了菱形继承,并且又要用到super,知道MRO就显得极为重要,我们使用C3算法来计算MRO

下面通过例子来解释:

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 N:
    pass
class O:
    pass
class M(N,O):
    pass
class G(E,M):
    pass
class H(G,F):
    pass

我们来计算上述代码的MRO

1.首先把继承树图画出来

是这样子的(不太好看,凑合一下)

2.假设C3算法是一个函数式,继承代表相加,然后把函数式写出来,很简单,看着继承树图写,不过顺序要与代码中继承的顺序相同

L(A) = A

L(B) = B + L(A)

L(C) = C + L(A)

L(D) = D + L(B) + L(C)

L(E) = E + L(C) + L(A)

L(F) = F + L(D) + L(E)

L(M) = M + L(N) + L(O)

L(G) = G + L(E) + L(M)

L(H) = H + L(G) + L(F)

3.函数式写出来了,下来我们进行化简

L(A) = A

L(B) = B + L(A) = BA

L(C) = C + L(A) = CA

L(D) = D + L(B) + L(C) = D + BA + CA =DBCA

L(E) = E + L(C) + L(A) = E + CA + A = ECA

L(F) = F + L(D) + L(E) = F + DBCA + ECA = FDBECA

L(M) = M + L(N) + L(O) = M + N + O =MNO

L(G) = G + L(E) + L(M) = G + ECA + MNO = GECAMNO

L(H) = H + L(G) + L(F) = H + GECAMNO + FDBECA = HGFDBECAMNO

函数式中的+代表的是merge(),merge规则:

 1. 如果第一个序列的第一个元素,是后续序列的第一个元素,或者不再后续序列中再次出现,则将这个元素合并到最终的方法解析顺序序列中,并从当前操作的全部序列中删除。

  2. 如果不符合,则跳过此元素,查找下一个列表的第一个元素,重复1的判断规则

最后我们可以来验证

print(H.__mro__)

发现顺序与我们算的顺序相同,只不过后边多了个class object,因为我们所有的类都要继承obj,所以也不足为奇

我们计算MRO就是要为super做铺垫,所以我们来看一道面试题

class Init(object):
    def __init__(self,v):
        print("init")
        self.val = v
class Add2(Init):
    def __init__(self,val):
        print("Add2")
        super(Add2,self).__init__(val)
        print(self.val)
        self.val += 2
class Mult(Init):
    def __init__(self,val):
        print("Mult")
        super(Mult, self).__init__(val)
        self.val *= 5
class HaHa(Init):
    def __init__(self,val):
        print("HaHa")
        super(HaHa,self).__init__(val)
        self.val /= 5
class Pro(Add2,Mult,HaHa):
    pass
class Incr(Pro):
    def __init__(self,val):
        super(Incr,self).__init__(val)
        self.val += 1
p = Incr(5)
print(p.val)

大致看一眼,发现出现了多个继承,还涉及到了super的用法,按照方法一步一步来

1.画继承树图

2.然后算出MRO:Incr,Pro,Add,Mult,Haha,Init,(Object)

3.super是访问MRO中下一个类的内容,秉持着这个原则我们进行稍加分析,这道题只不过是几个super的叠用,答案不难算出来

posted @ 2019-03-28 16:29  杨鸿儒  阅读(253)  评论(2编辑  收藏  举报