20 多继承 MRO 算法 深度优先遍历 super
类的多继承
一个类可以继承多个无关的类. 一个类可以被多个无关的类继承
1.经典类. 在python2.2之前. 已经是历史了. MRO 采用的是树形结构的深度递归遍历(一条道跑到黑)
2.新式类 在2.2之后产生新式类. 目前我们使用的. 所有的类的根都是object C3算法(merge)
#2 新式类的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 M(F, E): pass class N: pass class P(M,N): pass class G(P): pass class O: pass class X(O): pass class H(G, X, F): pass print(H.__mro__) #直接可以通过 print(类名.__mro_) 求某个类的mro 值 # #计算过程: # 原则 :合并. 从下向上合并. 拿出每一项的头和后一项的身体进行比较. 如果出现了. 就过, 从后一项的头继续去比较. 如果不出现就出来 # 结果为 HGPMXFDBECANO #设L为查找方法的MRO顺序 # L(H) = H + L(G) + L(X) + L(F) + GXF HGPMXFDBECANO # # L(G) = G + L(P) + P # GPMFDBECAN # L(X) = X + L(O) + O # XO # L(F) = F + L(D) + L(E) + DE # FDBECA # # # L(P) = P + L(M) + L(N) + MN # PMFDBECAN # L(D) = D + L(B) + L(C) + BC # DBCA # L(E) = E + L(C) + L(A) + CA # ECA # # L(M) = M + L(F) + L(E) + FE # ECA ECA E MFDBECA # # ''' # # # ''' # L(H) = H + L(G) + X+ L(F) HGPMFDBECAN FDBECA # # L(G) = G + L(P) GPMFDBECAN # L(F) = F + L(D) + L(E) FDBECA # # L(P) = P + L(M) + L(N) PMFDBECAN # L(D) = D + L(B) + L(C) DBCA # L(E) = E + L(C) + L(A) ECA # # L(M) = M + L(F) + L(E) MFDBECA # L(N) = N # L(B) = B + L(A) BA # L(C) = C + L(A) CA # # L(A) = A # 新式类通过__mro__可以直接看到MRO的结果
3. super MRO 的下一位
# super是查找mro顺序中的下一个 # 单继承中我们可以认为super是对父类中的属性或方法的引入 class ShengWu: def dong(self): # 实例方法 print(self) print("我是生物") class Animal(ShengWu): pass class Cat(Animal): def dong(self): # 子类中出现了和父类重名的内容. 表示对父类的方法的覆盖(重写). 半盖(java) super(Animal, self).dong() # 定位到Animal. 找Animal的下一个 # super(类, 对象).方法() 找到MRO中的类. 找这个类的下一个. 去执行方法 print("我的猫也会动") # 找MRO中的下一个 # Cat -> Animal -> ShengWu
4.面试题
class Init(object): def __init__(self, v): print("init") self.val = v # 2 class Add2(Init): def __init__(self, val): # 2 print("Add2") super(Add2, self).__init__(val) print(self.val) # 5.0 self.val += 2 # 7.0 class Mult(Init): def __init__(self, val): print("Mult") super(Mult, self).__init__(val) self.val *= 5 # 5.0 class HaHa(Init): def __init__(self, val): print("哈哈") super(HaHa, self).__init__(val) self.val /= 5 # 1.0 class Pro(Add2,Mult,HaHa): # pass class Incr(Pro): def __init__(self, val): # 5 super(Incr, self).__init__(val) self.val += 1 # 8.0 ''' add2 Mult 哈哈 init 5.0 8.0 Add2 init 2 4 ''' # Incr, pro, add2, mult, haha, Init p = Incr(5) print(p.val) # ? # Add2 init c = Add2(2) print(c.val) # ?
有疑问可以加wx:18179641802,进行探讨