Python - 对多继承以及super的一些了解
Python支持多继承,与C++一样都会出现一种问题:子类继承的多个父类又继承了同一个父类,这时就有可能会出现父类构造方法被调用多次的情况。关于这个问题,我找了一些资料,虽然没有亲自全部验证,这里我总结一下自己对这个问题的看法。
Python和C++的关于这个问题的解决方案不太一样,当然Python还要看它的版本。
C++用的方案是引入了虚继承的语法避免同一个类被构造了多次。
Python用的方法是MRO(method resolution order,方法解析顺序) 。在在Python2.3之前,MRO的实现是基于DFS的,而在Python2.3以后MRO的实现是基于C3算法。找到的资料解释了一下更换算法的原因:
1 # -*- coding:utf-8 -*- 2 3 class D(object): 4 def foo(self): 5 print "class D" 6 7 class B(D): 8 pass 9 10 class C(D): 11 def foo(self): 12 print "class C" 13 14 class A(B, C): 15 pass 16 17 f = A() 18 f.foo()
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
如果我用的是super来解决多继承的初始化问题的话,那么到底是怎么初始化的呢?
这是我一开始想到的一个问题:
1 class A(object): 2 def __init__(self,a): 3 print a 4 5 class B(object): 6 def __init__(self,a,b): 7 print a+b 8 9 class C(A,B): 10 def __init__(self): 11 super(C,self).__init__(?) 12 13 obj = C()
第十一行的那个'?'的位置到底是填是什么进去才对呢?
我一开始认为因为是多继承多以需要初始化父类的时候A,B都需要初始化,那么问题来了,super(C,self).__init__(?)怎么写?
我试了一下:
① ? = 1 --> 输出1
② ? = 1,2 --> TypeError: __init__() takes exactly 2 arguments (3 given)
定义C的时候改成class(B,A)
③ ? = 1 --> TypeError: __init__() takes exactly 3 arguments (2 given)
④ ? =1,2 --> 输出3
再来看另一段代码:
1 class A(object): 2 def func(self): 3 print 1 4 5 class B(object): 6 def __init__(self): 7 print 2 8 9 class C(A,B): 10 def __init__(self): 11 super(C,self).__init__() 12 13 obj = C() 14 #The output is 3
说明什么问题?在调用super(classname,self).__init__()的时候应该调用在继承的父类列表里面有实现__init__()这个方法而且最靠左边的那个父类的构造方法,而且这个__init__(?)的'?'一定要与父类列表的里面第一个有构造方法的父类的构造方法签名一样才可以。
所以如果需要对所有父类都进行一遍初始化,还是使用类通过类名调用未绑定的初始化方法好(我说这一句话是因为我还不是很了解super)。
说一下super的使用:
super( classname,对象(一般情况是self) ) 返回的是一个super对象,你可以把它当作父类列表里面有实现__init__()这个方法而且最靠左边的那个父类的一个对象就可以了。
参考文章地址:
http://blog.csdn.net/imzoer/article/details/8737642
http://blog.csdn.net/zyflying/article/details/8636006