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列列表的顺序往下找.否则⼀一切都是错的

 

posted @ 2018-11-13 21:30  Mixtea  阅读(344)  评论(0编辑  收藏  举报