zoukankan      html  css  js  c++  java
  • python D20 多继承、C3算法、super()

    # 今日大纲
    # 1、多继承
    # 继承:x是一种y的时候,可以使用继承关系."is a"
    # 一个类同时继承多个类(python, c++)
    # eg:孙悟空是猴子,还是神仙,还是妖怪

    # 2、经典类的MRO
    # 通过树形结构的深度优先遍历
    # 一条道走到黑(从左往右)

    # 3、新式类的MRO(重点、面试题)c3算法
    # 先拆分
    # 在合并,第一项的头和后面所有项的身子(除了头以外的部分)进行比较,如果都没有就拿出来,如果出现了,就跳过到后一项,后一项查一个完在跳会原来的位置继续上述动作

    # 4、super() (重点)
    # 找MRO(新式的)的顺序的下一个

    # 一、pytohn多继承
    # python支持多继承,一个类可以拥有多个父类
    # class ShenXian: # 神仙
    # def fei(self):
    # print("神仙都会⻜")
    # class Monkey: # 猴
    # def chitao(self):
    # print("猴⼦喜欢吃桃⼦")
    # class SunWukong(ShenXian, Monkey): # 孙悟空是神仙, 同时也是⼀只猴
    # pass
    # sxz = SunWukong() # 孙悟
    # sxz.chitao() # 会吃桃⼦
    # sxz.fei() # 会⻜

    # 多继承存在一个问题,当出现两个父类中出现虫棉方法的时候,该怎么办
    # 这就涉及到如何查找父类方法的这么一个问题,即MRO(method resolution order)
    # 问题,在python中这是一个复杂的问题,因为在不同的python版本中使用的是不同的算法来
    # 完成MRO的,首先我们能见到的有两个版本python2/python3
    # python2
    # 一个交经典类,在python2.2之前,一直使用的是经典类,经典类的在
    # 基类的跟如果什么都不写,表示继承xxx
    # 一个叫新式类,在python2.2之后出现了新式类,新式类的特点是
    # 基类的跟是object

    # python3
    # python3中使用的都是新式类,如果基类谁都不继承,拿这个类会默认继承object

    # 二、经典类的MRO
    # 经典类的MRO:通过树形结构的深度优先遍历 一条道走到黑(从左往右)

    # 三、新式类的MRO
    # python中的新式类的MRO是采用C3算法来完成的
    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 G(E):
    pass
    class H(G, F):
    pass
    # 首先我们确定从H开始找,也就是说创建的是H的对象
    # 如果重H找,那找到H+H的父类C3,我们设C3算法是L(x)
    # L(H) = H + L(G) + L(F) +(GF) = H + (GECA) + (FDBECA) + (GF) = (HGFDBECA) # 特别注意当头与后面所有项的身子比较时,如果后面身子项出现该项,在跳到下一项,下一项比较一个完在跳回原来的位置以此往复,如果后面项没有则拿出此项
    # L(G) = G + L(E) +(E) = G + (ECA) + E = (GECA)
    # L(F) = F + L(D) + L(E) + (DE) = F + (DBCA) + (ECA) +(DE) = (FDBECA)
    # L(E) = E + L(C) + L(A) +(CA) = E + (CA) + A + (CA) = (ECA)
    # L(D) = D + L(B) + L(C) +BC = D + (BA) + (CA) =(DBCA)
    # L(B) = B + L(A) + A = (BA)
    # L(C) = C +L(A) +A = (CA)
    # H.__mro__可以查看H的C3算法的排列
    # print(H.__mro__)
    # (<class '__main__.H'>, <class '__main__.G'>, <class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)

    # 四、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()⽅法
    # print("我的⽼家. 就住在这个屯")
    # class Bar:
    # def func1(self):
    # print("你的⽼家. 不在这个屯")
    #
    # class Ku(Foo, Bar):
    # def func1(self):
    # super().func1() # 此时super找的是Foo
    # print("他的⽼家. 不知道在哪个屯")

    # k = Ku() # 先看MRO . KU, FOO, BAR object
    # k.func1()
    # k2 = Foo() # 此时的MRO. Foo object
    # k2.func1() # 报错 # Foo这个类没有继承 直接报错

    # 面试题
    # 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)

    # 结果: 分析:复杂的先找出C3排序、一项项往上找
    # Add2
    # Mult
    # 哈哈
    # init
    # 5.0
    # 8.0
    # Add2
    # init
    # 2
    # 4
  • 相关阅读:
    贷款计算公式
    P2P行业专业术语(最全)
    p2p投资理财入门篇(新手必备)
    2015年p2p网络借贷平台的发展现状
    MyEclipse中SVN的常见的使用方法
    linux下打开、关闭tomcat,实时查看tomcat运行日志
    Spring 向页面传值以及接受页面传过来的参数的方式
    Spring自定义一个拦截器类SomeInterceptor,实现HandlerInterceptor接口及其方法的实例
    PowerDesigner概述(系统分析与建模)以及如何用PowerDesigner快速的创建出这个数据库
    MySQL 8.x 函数和操作符,官方网址:https://dev.mysql.com/doc/refman/8.0/en/functions.html
  • 原文地址:https://www.cnblogs.com/z520h123/p/9960293.html
Copyright © 2011-2022 走看看