zoukankan      html  css  js  c++  java
  • 菱形继承问题

    一、类的分类

    1.1 新式类

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

    • Python3中所有的类都是新式类

    1.2 经典类

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

    • 只有Python2中才有经典类

    二、菱形继承问题

    92-菱形继承问题-继承关机.jpg?x-oss-process=style/watermark

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

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

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

    • 经典类下:深度优先

    • 广度优先:广度优先

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

    92-菱形继承问题-经典类.png?x-oss-process=style/watermark

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

    92-菱形继承问题-新式类.png?x-oss-process=style/watermark

    class G(object):
        # def test(self):
        #     print('from G')
        pass
    
    
    print(G.__bases__)
    
    
    class E(G):
        # def test(self):
        #     print('from E')
        pass
    
    
    class B(E):
        # def test(self):
        #     print('from B')
        pass
    
    
    class F(G):
        # def test(self):
        #     print('from F')
        pass
    
    
    class C(F):
        # def test(self):
        #     print('from C')
        pass
    
    
    class D(G):
        # def test(self):
        #     print('from D')
        pass
    
    
    class A(B, C, D):
        def test(self):
            print('from A')
    
    
    obj = A()
    
    (<class 'object'>,)
    
    obj.test()  # A->B->E-C-F-D->G-object
    
    from A
    

    三、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. 如果对下一个类存在两个合法的选择,选择第一个父类
  • 相关阅读:
    Excel 2016 Power View选项卡不显示的问题
    Base64编码
    MAPI错误0x80040107
    命令行界面 (CLI)、终端 (Terminal)、Shell、TTY的区别
    C函数调用过程原理及函数栈帧分析
    SIFT(Scale-invariant feature transform) & HOG(histogram of oriented gradients)
    Jupyter NoteBook 的快捷键
    endnote插入参考文献后的对齐方式和缩进空格
    赏月斋源码共享计划 第四期 约瑟夫问题
    LRU和LFU的区别
  • 原文地址:https://www.cnblogs.com/nickchen121/p/10272737.html
Copyright © 2011-2022 走看看