classA:pass
classB(A):pass
classC(A):pass
classD(B, C):pass
classE(C, A):pass
classF(D, E):pass
classG(E):pass
classH(G, F):pass
⾸先. 我们要确定从H开始找. 也就是说. 创建的是H的对象
⾸首先. 我们要确定从H开始找. 也就是说. 创建的是H的对象. 如果从H找. 那找到H+H的⽗父类的C3, 我们设C3算法是L(x) , 即给出x类. 找到x的MRO
L(H) = H + L(G) + L(F) + GF
继续从代码中找G和F的⽗父类往⾥里里⾯面带
L(G) = G + L(E) + E
L(F) = F + L(D)+ L(E) + DE
继续找E 和 D
L(E) = E + L(C) + L(A) + CA
L(D) = D + L(B) + L(C) + BC
继续找B和C
L(B) = B + L(A) + A
L(C) = C + L(A) + A
最后就剩下⼀一个A了了. 也就不⽤用再找了了. 接下来. 把L(A) 往⾥里里带. 再推回去. 但要记住. 这⾥里里的 + 表⽰示的是merge.
merge的原则是⽤用每个元组的头⼀一项和后⾯面元组的除头⼀一项外的其他元 素进⾏行行比较, 看是否存在. 如果存在.
就从下⼀一个元组的头⼀一项继续找. 如果找不到. 就拿出来. 作为merge的结果的⼀一项. 以此类推. 直到元组之间的元素都相同. 也就不⽤用再找了了.
L(B) =(B,) + (A,) + (A) -> (B, A)
L(C) =(C,) + (A,) + (A) -> (C, A)
继续带.
L(E) = (E,) + (C, A) + (A) + (C,A) -> E, C, A
L(D) = (D,) + (B, A) + (C, A) + (B, C) -> D, B, C, A
继续带.
L(G) = (G,) + (E, C, A) + (E) -> G, E, C, A
L(F) = (F,) + (D, B, C, A) + (E, C, A) + (D, E)-> F, D, B, E, C, A
加油, 最后了了
L(H) = (H, ) + (G, E, C, A) + ( F, D, B, E, C, A) + (G, F) -> H, G, F, D, B, E, C,
验证
使⽤用类名.__mro__获取到类的MRO信息.
(, , , ,
, , , , )
C3是把我们多个类产生的共同继承留到最后去找,所以,我们也可以从图上来看到相关的规律,这个要大家自己多谢多画图就可以感觉到。但是如果没有所谓的共同继承关系。那几乎就当成是深度遍历就可以了。
4、super() 找MRO顺序的下一个
super()可以帮我们执行MRO中下一个父类的方法,通常super()有两个使用的地方:
1、可以访问父类的构造方式
2、当子类方法想调用父类(MRO)中的方法
第一种
classFoo:def __init__(self,a,b,c):
self.a=a
self.b=b
self.c=cclassBar(Foo):def __init__(self,a,b,c,d):
super().__init__(a,b,c) #访问父类的构造方法
self.d =d
b= Bar(1,2,3,4)print(b.__dict__)#{'a': 1, 'b': 2, 'c': 3, 'd': 4}
第二种
classFoo:deffunc1(self):
super().func1()#此时要找的是MRO顺序中下一个类的func1()方法
print("我的老家就住在这个屯")classBar:deffunc1(self):print("你的老家不在这个屯")classKu(Foo,Bar):deffunc1(self):
super().func1()#此时super找的是Foo
print("他的老家不知道在哪个屯")
k= Ku() #先看MRO,Ku,Foo,Bar,object
k.func1()#你的老家不在这个屯#我的老家就住在这个屯#他的老家不知道在哪个屯
5、一道面试题
#MRO + super 面试题
classInit(object):def __init__(self, v):print("init")
self.val=vclassAdd2(Init):def __init__(self, val):print("Add2")
super(Add2, self).__init__(val)print(self.val)
self.val+= 2
classMult(Init):def __init__(self, val):print("Mult")
super(Mult, self).__init__(val)
self.val*= 5
classHaHa(Init):def __init__(self, val):print("哈哈")
super(HaHa, self).__init__(val)
self.val/= 5
classPro(Add2,Mult,HaHa):pass
classIncr(Pro):def __init__(self, val):
super(Incr, self).__init__(val)
self.val+= 1
#Incr Pro Add2 Mult HaHa Init
p = Incr(5)print(p.val)
c= Add2(2)print(c.val)#Add2#Mult#哈哈#init#5.0#8.0#Add2#init#2#4