• C3算法 和 super


    一. Python的继承  多继承

      子类继承父类. 

      继承是为了节省开发时间.提高开发效率 代码得到了重(chong)用 一个类可以拥有多个父类

    lass shen_xian:  #  定义一个神仙类
        def fei(self):  # 神仙类有一个方法 可以飞
            print('神仙都会飞')
    class Monkey: # 定义一个猴子类
        def chitao(self): # 猴子有一个方法 可以吃桃子
            print('猴子喜欢吃桃')
    class SunWuKong(Monkey,shen_xian): # 对象继承猴子和神仙的类型
        pass
    sxz = SunWuKong()  # 实例化一个孙悟空对象
    sxz.chitao()   # 会吃桃子
    sxz.fei()   # 会飞

      多继承用起来简单 但是存在一个问题 当父类中出现重名方法时 就涉及到查找父类方法中的问题 也即MRO(method resolution order)

    二. 经典类的MRO

      在Python2中存在两种类 

        经典类 : 在Python 2.2 之前 一直使用的是 经典类 

        新式类 : 在2.2之后 出现了新式类 特点是 基类的根是object

      Python 3 

        只有新式类  如果基类谁都不继承 那么会默认继承object

      经典类的MRO 深度优先遍历 例如 快递员送鸡蛋 :

     

      肯定是按照123456顺序来送 即每次都是最左边 找完撤回到分叉口继续往里找(从左往右,一条道跑到黑,然后撤回继续一条道跑到黑) 即深度优先遍历   如果 142356 就是广度优先遍历

    三. 新式类的MRO, C3(重点, 难点)  可以通过 类名.__mro__ 获取到类的mro信息

      即print(类名.__mro__) 就可以获取到

        Python中的新式类的mro都是用 c3算法来完成的

            笔试的时候肯定会考

      新式类中摒弃了(部分). C3算法   

      如果继承关系没有菱形继承(深度优先)

      如果有菱形:使用C3算法来计算MRO 

    三. super

      super()可以执行 mro中的下一个父类的方法 通常super()有两个使用的地方 :

        1 . 可以访问父类的构造方法

        2 . 当子类方法想调用父类(mro)中的方法 

        先看第一种

    class Foo:
        def __init__(self,a,b,c):
            self.a = a
            self.b = b
            self.c = c
    class Bar(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}

      这样就方便了子类 不需要写那么多了

      第二种 

    class Foo:
        def func1(self):
            super().func1()   # 此时找的是mro顺序中下一个类的func1()方法 实际到这就会报错 根本不会运行 
            # 因为 Foo 中没有func1方法 继承的obj中也没有func1()方法 
            print('我的老家,就住在这个屯')
    class Bar:
        def func(self):
            print('你的老家,不在这个屯')
    class Ku(Foo,Bar):
        def func1(self):
            super().func1()
            print('它的老家,不知道在哪个屯')
    k = Ku()  # 先看mro Ku , Foo, Bar ,object
    k.func1()  
    
    k2 = Foo()  # 此时的mro Foo , object 都没有func1 因此会报错 如果这样写一开始就会报错 就不会运行到这才报错
    k2.func1()

    五. 一道面试题

    # mro + super 面试题
    class Init:
        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
    p = Incr(5)
    print(p.val)
    c = Add2(2)
    print(c.val)
    View Code

      结论 : 不管super()写在哪. 在哪执行,一定先找到mro列表.根据mro列表的顺序往下找 否则都是错的.

  • 相关阅读:
    Android设备管理器
    Android中读取手机联系人
    PopupWindow
    Activity之间数据的传递
    wpa_supplicant
    nandflash之基本特性
    NAND NOR Flash 和MTD
    mtd-util
    linux 常用命令
    minizip -基于zlib开源代码库
  • 原文地址:https://www.cnblogs.com/f-g-f/p/9729064.html
Copyright © 2020-2023  润新知