zoukankan      html  css  js  c++  java
  • Python3学习之路~6.7 经典类和新式类的继承顺序

    在Python中,经典类(class Person:)和新式类(class Person(object):)的主要区别就是体现在多继承的顺序上。

    Python 2.x中默认都是经典类,只有显式继承了object才是新式类;
    Python 3.x中默认都是新式类,不必显式地继承object。

    假设现在有一个D类继承了B类和C类,B类和C类又分别继承了A类。

    在Python2.7中分别执行如下经典类代码:

    # Author:Zheng Na
    # encoding=utf-8
    #当D类中有构造函数时,实例化时会执行D类的构造函数
    class A:
        def __init__(self):
            print("A")
    
    class B(A):
        def __init__(self):
            print("B")
    
    class C(A):
        def __init__(self):
            print("C")
    
    class D(B,C):
        def __init__(self):
            print("D")
    
    d = D() #输出:D
    当D类中有构造函数时,实例化时会执行D类的构造函数
    # Author:Zheng Na
    # encoding=utf-8
    #当D类中没有构造函数时,实例化时会执行B类的构造函数
    class A:
        def __init__(self):
            print("A")
    
    class B(A):
        def __init__(self):
            print("B")
    
    class C(A):
        def __init__(self):
            print("C")
    
    class D(B,C):
        pass
    
    d = D() #输出:B
    当D类中没有构造函数时,实例化时会执行B类的构造函数
    # Author:Zheng Na
    # encoding=utf-8
    #当D类、B类中没有构造函数时,实例化时会执行A类的构造函数
    class A:
        def __init__(self):
            print("A")
    
    class B(A):
        pass
    
    class C(A):
        def __init__(self):
            print("C")
    
    class D(B,C):
        pass
    
    d = D() #输出:A
    当D类、B类中没有构造函数时,实例化时会执行A类的构造函数
    # Author:Zheng Na
    # encoding=utf-8
    #当D类、B类、A类中没有构造函数时,实例化时会执行C类的构造函数
    class A:
        pass
    
    class B(A):
        pass
    
    class C(A):
        def __init__(self):
            print("C")
    
    class D(B,C):
        pass
    
    d = D() #输出:C
    当D类、B类、A类中没有构造函数时,实例化时会执行C类的构造函数

    你会发现,Python2.7中经典类的继承顺序是深度优先策略,先一级一级的往上查找,查到根部没有的话,再返回下一级查找。

    在Python2.7中分别执行如下新式类代码:

    # Author:Zheng Na
    # encoding=utf-8
    # 当D类中有构造函数时,实例化时会执行D类的构造函数
    class A(object):
        def __init__(self):
            print("A")
    
    
    class B(A):
        def __init__(self):
            print("B")
    
    
    class C(A):
        def __init__(self):
            print("C")
    
    
    class D(B, C):
        def __init__(self):
            print("D")
    
    
    d = D()  # 输出:D
    当D类中有构造函数时,实例化时会执行D类的构造函数
    # Author:Zheng Na
    # encoding=utf-8
    # 当D类中没有构造函数时,实例化时会执行B类的构造函数
    class A(object):
        def __init__(self):
            print("A")
    
    
    class B(A):
        def __init__(self):
            print("B")
    
    
    class C(A):
        def __init__(self):
            print("C")
    
    
    class D(B, C):
        pass
    
    d = D()  # 输出:B
    当D类中没有构造函数时,实例化时会执行B类的构造函数
    # Author:Zheng Na
    # encoding=utf-8
    # 当D类、B类中没有构造函数时,实例化时会执行C类的构造函数
    class A(object):
        def __init__(self):
            print("A")
    
    
    class B(A):
        pass
    
    
    class C(A):
        def __init__(self):
            print("C")
    
    
    class D(B, C):
        pass
    
    d = D()  # 输出:C
    当D类、B类中没有构造函数时,实例化时会执行C类的构造函数
    # Author:Zheng Na
    # encoding=utf-8
    # 当D类、B类、C类中没有构造函数时,实例化时会执行A类的构造函数
    class A(object):
        def __init__(self):
            print("A")
    
    class B(A):
        pass
    
    class C(A):
        pass
    
    class D(B, C):
        pass
    
    d = D()  # 输出:A
    当D类、B类、C类中没有构造函数时,实例化时会执行A类的构造函数

     你会发现,Python2.7中新式类的继承顺序是广度优先策略,先在上一级从左到右查找一遍,没有的话,再到上上一级从左到右查找一遍,以此类推。

     

      经典类 新式类
    Python2.x 深度优先 广度优先
    Python3.x 广度优先 广度优先

    Python2.x的经典类是按照深度优先策略来继承的,新式类是按照广度优先策略来继承的。
    Python3.x的经典类和新式类统一都是按照广度优先策略来继承的。

    这并不是Python 2.x中的一个bug,只能算是一种策略。由于在大多数情况下,深度优先的效率没有广度优先高,所以在Python 3.x中才全部改为了广度优先。

    另外,super()也是新式类的用法。

    附:官方文档 https://www.python.org/doc/newstyle/

  • 相关阅读:
    [洛谷P3931]SAC E#1
    洛谷 P4127 [AHOI2009]同类分布 解题报告
    洛谷 P4475 巧克力王国 解题报告
    洛谷 P4148 简单题 解题报告
    洛谷 P2463 [SDOI2008]Sandy的卡片 解题报告
    洛谷 P4211 [LNOI2014]LCA 解题报告
    洛谷 P4074 [WC2013]糖果公园 解题报告
    AT1219 歴史の研究 解题报告
    洛谷 P4137 Rmq Problem /mex 解题报告
    THUWC2019 摸鱼记
  • 原文地址:https://www.cnblogs.com/zhengna/p/9603741.html
Copyright © 2011-2022 走看看