python中多继承的问题(比较C++的多继承)

来源:互联网 发布:unity3d按轨迹运动 编辑:程序博客网 时间:2024/05/19 18:48

python的多继承类是通过mro的方式来保证各个父类的函数被逐一调用,而且保证每个父类函数都只被调用一次

和C++不同的是:

1.如果子类中没有作显示调用!并且父类的构造__init__()中不需要传入额外的参数。那么,很明显的,父类的__init__不会被调用

class A():    def __init__(self):        print('A')class B(A):    def __init__(self):        print('B')b = B()        
很明显的,只输出'B'

2.在多继承当中,python对于多继承类的调用机制是 1。当某个类D多继承类B,C,E。那么走B的构造的时候

(1)若B、C、E的父类不同!也就是不出现重复继承的问题!则按照正常的顺序D构造->B->B的父类,C->C的父类 D

如下所示,他们各不影响

class A:    def __init__(self):        print('A')class S:    def __init__(self):        print('S')        print('L_S')class M:    def __init__(self):        print('M')        print('L_M')class B(A):    def __init__(self):        print('B')        super(B,self).__init__()        print('L_B')class C(S):    def __init__(self):        print('C')        super(C,self).__init__()        print('L_C')class D(M):    def __init__(self):        print('D')        super(D,self).__init__()        print('L_D')class E(B,C,D):    def __init__(self):        B.__init__(self)        C.__init__(self)        D.__init__(self)        print('L_E')d = E()
结果!
BAL_BCSL_SL_CDML_ML_DL_E
(2).若B、C、E的父类有一个或者多个是相同的,则父类不相同的,走到父类,父类相同的,待都走完再走父类

若C、E父类相同,B与CE父类不同,则先走B->B的父类->C->E->(CE的父类)

(PS:关于原理。。真实很晕。。这时候我想到了C语言的多继承问题)

  他们的内存图假设是这样的:  B继承M  MB

                                                     C继承A   AC

                                                     E继承A    AE

如果用C++虚继承的概念来理解:( *pA C *pA E A)  *pA指向A ,那就不难理解!为什么是C->E->A了!

class A:    def __init__(self):        print('A')class S:    def __init__(self):        print('S')        print('L_S')class M:    def __init__(self):        print('M')        print('L_M')class B(S):    def __init__(self):        print('B')        super(B,self).__init__()        print('L_B')class C(A):    def __init__(self):        print('C')        super(C,self).__init__()        print('L_C')class D(A):    def __init__(self):        print('D')        super(D,self).__init__()        print('L_D')class E(B,C,D):    def __init__(self):        B.__init__(self)        C.__init__(self)        D.__init__(self)        print('L_E')d = E()
输出:

BSL_SL_BCDAL_DL_CDAL_DL_E
3.python提供了一种机制,super()来避免这种重复的问题!类似于虚继承:
  
class E(B,C,D):    def __init__(self):        <strong>super().__init__()</strong>        print('L_E')d = E()

输出:

B
S
L_S
L_B

PS:(纳尼!咋回事!!!!! CD呢)

原来。。根据以上的路线,为了避免基类的重复,他只会走到类的顶端最上层就停下!

如果调用E继承CD,那么走C的时候,C->D->A的时候就终止了!不会继续走

<pre name="code" class="python">class A:    def __init__(self):        print('A')class S:    def __init__(self):        print('S')        print('L_S')class M:    def __init__(self):        print('M')        print('L_M')class B(S):    def __init__(self):        print('B')        super(B,self).__init__()        print('L_B')class C(A):    def __init__(self):        print('C')        super(C,self).__init__()        print('L_C')class D(A):    def __init__(self):        print('D')        super(D,self).__init__()        print('L_D')class E(C,D):    def __init__(self):        super(E,self).__init__()d = E()
输出
C
D

A

L_D

L_C


总结(摘自http://www.cnblogs.com/lovemo1314/archive/2011/05/03/2035005.html)

1. super并不是一个函数,是一个类名,形如super(B, self)事实上调用了super类的初始化函数, 产生了一个super对象; 

2. super类的初始化函数并没有做什么特殊的操作,只是简单记录了类类型和具体实例;  

3. super(B, self).func的调用并不是用于调用当前类的父类的func函数; 

4. Python的多继承类是通过mro的方式来保证各个父类的函数被逐一调用,而且保证每个父类函数只调用一次(如果每个类都使用super);  

5. 混用super类和非绑定的函数是一个危险行为,这可能导致应该调用的父类函数没有调用或者一个父类函数被调用多次。


0 0
原创粉丝点击