在程序中出现了多个类的继承而且出现了菱形继承,并且又要用到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 + L(A)
L(D) = D + L(B) + L©
L(E) = E + L© + 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 + L(A) = CA
L(D) = D + L(B) + L© = D + BA + CA =DBCA
L(E) = E + L© + 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的叠用,答案不难算出来