继承是面向对象编程的一个重要的方式,经过继承,子类就能够扩展父类的功能。在python中一个类能继承自不止一个父类,这叫作python的多重继承(Multiple Inheritance )。html
语法python
class SubclassName(BaseClass1, BaseClass2, BaseClass3, ...): pass
在多层继承和多继承同时使用的状况下,就会出现复杂的继承关系,多重多继承。算法
其中,就会出现菱形继承。以下图所示。编程
在这种结构中,在调用顺序上就出现了疑惑,调用顺序到底是如下哪种顺序呢微信
下面咱们来解答下这个问题。spa
举个例子来看下:code
class A(): def __init__(self): print('init A...') print('end A...') class B(A): def __init__(self): print('init B...') A.__init__(self) print('end B...') class C(A): def __init__(self): print('init C...') A.__init__(self) print('end C...') class D(B, C): def __init__(self): print('init D...') B.__init__(self) C.__init__(self) print('end D...') if __name__ == '__main__': D()
输出结果htm
init D... init B... init A... end A... end B... init C... init A... end A... end C... end D...
从输出结果中看,调用顺序为:D->B->A->C->A。能够看到,B、C共同继承于A,A被调用了两次。A不必重复调用两次。对象
其实,上面问题的根源都跟MRO有关,MRO(Method Resolution Order)也叫方法解析顺序,主要用于在多重继承时判断调的属性来自于哪一个类,其使用了一种叫作C3的算法,其基本思想时在避免同一类被调用屡次的前提下,使用广度优先和从左到右的原则去寻找须要的属性和方法。blog
那么如何避免顶层父类中的某个方法被屡次调用呢,此时就须要super()来发挥做用了,super本质上是一个类,内部记录着MRO信息,因为C3算法确保同一个类只会被搜寻一次,这样就避免了顶层父类中的方法被屡次执行了,上面代码能够改成:
class A(): def __init__(self): print('init A...') print('end A...') class B(A): def __init__(self): print('init B...') super(B, self).__init__() print('end B...') class C(A): def __init__(self): print('init C...') super(C, self).__init__() print('end C...') class D(B, C): def __init__(self): print('init D...') super(D, self).__init__() print('end D...') if __name__ == '__main__': D()
输出结果:
init D... init B... init C... init A... end A... end C... end B... end D...
能够看出,此时的调用顺序是D->B->C->A。即采用是广度优先的遍历方式。
Python类分为两种,一种叫经典类,一种叫新式类。都支持多继承,但继承顺序不一样。
Python2.x中类的是有经典类和新式类两种。Python3.x中都是新式类。
打开微信扫一扫,关注【西加加先生】微信公众号,及时接收博文推送。
原文出处:https://www.cnblogs.com/ghostlee/p/12298294.html