• 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列列表的顺序往下找.否则⼀一切都是错的
  • 相关阅读:
    CentOS 7 和centos6切换图形界面和多用户界面
    centos6.8下安装elasticsearch
    一个xib钟多个Cell
    iOS frame从导航栏下面开始
    Xcode 移除(卸载)插件
    iOS9 HTTP传输安全
    pch头文件
    真机调试---打包6plus出现问题
    Xcode 添加类前缀
    iOS 状态栏黑色背景白色字体
  • 原文地址:https://www.cnblogs.com/Mixtea/p/9954910.html
Copyright © 2020-2023  润新知