• 菱形继承问题


    菱形继承问题

    一、类的分类

    1.1 新式类

    • 继承了object的类以及该类的子类,都是新式类
    • Python3中所有的类都是新式类

    1.2 经典类

    • 没有继承object的类以及该类的子类,都是经典类
    • 只有Python2中才有经典类

    二、菱形继承问题

    在Java和C#中子类只能继承一个父类,而Python中子类可以同时继承多个父类,如A(B,C,D)

    如果继承关系为非菱形结构,则会按照先找B这一条分支,然后再找C这一条分支,最后找D这一条分支的顺序直到找到我们想要的属性

    如果继承关系为菱形结构,即子类的父类最后继承了同一个类,那么属性的查找方式有两种:

    • 经典类下:深度优先
    • 广度优先:广度优先
    • 经典类:一条路走到黑,深度优先

    • 新式类:不找多各类最后继承的同一个类,直接去找下一个父类,广度优先

    # 继承菱形问题: 新式类和经典类的查找顺序不一样
    # 新式类的查找属性:广度优先
    # 经典类:深度优先
    
    class G():
        a = 'ggg'
    
    
    class F(G):
        a = 'fff'
    
    
    class E(F):
        a = 'eee'
    
    
    class D(E):
        a = 'ddd'
    
    
    class C(D):
        a = 'ccc'
    
    
    class B(C):
        a = 'bbb'
    
    
    class A(B, C, D):
        a = 'aaa'
    
    a = A()
    print(a.a)
    
    # mro 列表,查看继承顺利列表(只在新式类中有)
    print(A.mro())
    print(A.__mro__)
    
    
    
    obj = A()
    (<class 'object'>,)
    obj.test()  # A->B->E-C-F-D->G-object
    from A
    
    • 继承菱形问题在python3中显示的都是继承一个类,不是object类, 新式类和经典类的查找顺序是不一样
    • 新式类(python3中全是新式类):广度优先---从左侧开始,一直往上找,找到菱形的顶点结束(不包含菱形顶点),继续下一个继承父类往上找,找到菱形的顶点结束(不包含括菱形的顶点),最后找到菱形顶点
    • 经典类(python2中才有):深度优先搜索---从左侧开始,一直往上找,找到菱形顶点结束(包括菱形顶点),继续下一个继承父类往上找,找到菱形的顶点结束(不包含菱形顶点)

    三、C3算法与mro()方法介绍

    [92-菱形继承问题-飞船原理.jpg?x-oss-process=style/watermark

    python到底是如何实现继承的,对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表,如:

    print(A.mro())  # A.__mro__
    
    

    [<class 'main.A'>, <class 'main.B'>, <class 'main.E'>, <class 'main.C'>, <class 'main.F'>, <class 'main.D'>, <class 'main.G'>, <class 'object'>]

    
    for i in A.mro():
        print(i)
    
    <class '__main__.A'>
    <class '__main__.B'>
    <class '__main__.E'>
    <class '__main__.C'>
    <class '__main__.F'>
    <class '__main__.D'>
    <class '__main__.G'>
    <class 'object'>
    

    为了实现继承,python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止。

    而这个MRO列表的构造是通过一个C3线性化算法来实现的。我们不去深究这个算法的数学原理,它实际上就是合并所有父类的MRO列表并遵循如下三条准则:

    1. 子类会先于父类被检查
    2. 多个父类会根据它们在列表中的顺序被检查
    3. 如果对下一个类存在两个合法的选择,选择第一个父类
    在当下的阶段,必将由程序员来主导,甚至比以往更甚。
  • 相关阅读:
    用C语言实现最小二乘法算法
    设计单片机日志系统
    自律的人有多可怕?(深度好文
    史上最强灯光模拟
    堡垒机
    科三路考规则还能这样记?简直神了!
    2018驾考科目三考试流程及注意事项
    安装CentOS7文字界面版后,无法联网,用yum安装软件提示 cannot find a valid baseurl for repo:base/7/x86_64 的解决方法
    什么是EPEL 及 Centos上安装EPEL(转)
    【Nginx安装】CentOS7安装Nginx及配置
  • 原文地址:https://www.cnblogs.com/randysun/p/12249192.html
Copyright © 2020-2023  润新知