python基础之面向对象的多继承以及MRO算法
内容梗概:
1. python多继承
2. python经典类的MRO
3. python新式类的MRO C3算法
1.python多继承
class Shen: def fly(self): print("大神会飞") class Hou: def chi(self): print("猴子吃桃子") class SunWuKong(Shen, Hou): # 一个类可以继承多个无关的类. 一个类可以被多个无关的类继承 pass class TaiShangLaoJun(Shen): pass swk = SunWuKong() swk.fly() swk.chi()
2. 经典类的MRO
在经典类中采用的是深度优先遍历方案.什什么是深度优先.就是一条路路走到头.然后再回来.继续找下一个
三. 新式类的MRO
实例1
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 H(G, F): pass print(H.__mro__) L(H) = H + L(G) + L(F) + GF HGPMFDBECAN L(G) = G + L(P) + P GPMFDBECAN 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 MFDBECA L(N) = N L(B) = B + L(A) + A BA L(C) = C + L(A) + A CA L(A) = A
实例2
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__) L(H) = H + L(G) + L(X) + L(F) + GXF HGPM XFDB ECA NO 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 MFDBECA L(N) = N N L(B) = B + L(A) + A BA L(C) = C + L(A) + A CA L(A) = A
4. super是什么鬼?
super()可以帮我们执行MRO中下一个父类的⽅方法. 通常super()有两个使用的地方:
1. 可以访问父类的构造方法
2. 当子类方法想调⽤父类(MRO)中的方法
super是查找mro顺序中的下一个
单继承中我们可以认为super是对父类中的属性或方法的引入
实例:
class ShengWu: def dong(self): # 实例方法 print("我是生物") class Animal(ShengWu): def chi(self): # 实例方法 print("我是动物") class Cat(Animal): def dong(self): # 子类中出现了和父类重名的内容. 表示对父类的方法的覆盖(重写). 半盖(java) super(Animal, self).dong() # 定位到Animal. 找Animal的下一个(第三层) py2的写法 super().dong() # 直接跳到第三层 ,py3的写法 super().chi() # 跳到第二层 ,py3的写法 super(类, 对象).方法() 找到MRO中的类. 找这个类的下一个.去执行方法 print("我的猫也会动") 找MRO中的下一个 Cat -> Animal -> ShengWu c = Cat() print(c) c.dong()
补充:
# 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("哈哈") 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 # Incr Pro Add2 Mult HaHa Init p = Incr(5) print(p.val) c = Add2(2) print(c.val) 提示. 先算MRO.然后看清楚self是谁. 结论: 不管super()写在哪儿.在哪儿执行. 一定先找到MRO列表 根据MRO列列表的顺序往下找.否则⼀一切都是错的