一、在Python类的方法(method)中,要调用父类的某个方法,可以有如下写法
class A(object):
def __init__(self):
print "enter A"
print "leave A"
class B(A):
def __init__(self):
print "enter B"
A.__init__(self)
print "leave B"
b=B()
结果
enter B
enter A
leave A
leave B
如果B的父类改变为C,如上例子只需要修改2处而已(将B类中的A换成C),这种调用方法在代码量大的情况下不可取,即引入super机制
官网解释super(type[, object-or-type]):
返回type的父类,如果第二个参数遗漏,则父类是非绑定的,如果第二个参数为object,则isinstance(obj,type)需为真,如果第二个参数为type,则issubclass(type2,type)需为真,super()必须作用于新式类。
改写如下(绑定),其中self是B的一个实例:
class A(object):
def __init__(self):
print "enter A"
print "leave A"
class B(A):
def __init__(self):
print "enter B"
super(B,self).__init__()
print "leave B"
b=B()
二、多重继承情况:
非绑定情况
class A(object):
def __init__(self):
print "enter A"
print "leave A"
class B(A):
def __init__(self):
print "enter B"
A.__init__(self)
print "leave B"
class C(B,A):
def __init__(self):
print "enter C"
B.__init__(self)
A.__init__(self)
print "leave C"
c=C()
enter C
enter B
enter A
leave A
leave B
enter A
leave A
leave C
看出A被调了2次,改用super,
class A(object):
def __init__(self):
print "enter A"
print "leave A"
class B(A):
def __init__(self):
print "enter B"
super(B,self).__init__()
print "leave B"
class C(B,A):
def __init__(self):
print "enter C"
super(C,self).__init__()
print "leave C"
c=C()
结果:
enter C
enter B
enter A
leave A
leave B
leave C
这里只被调用一次
三、多重继承机制
python super多重继承机制为mro(
Method resolution order)
比如上面的例子MRO即为 C B A ,super调用的为MRO中的下一个方法
class A(object):
2 def __init__(self):
3 print "A"
4 super(A,self).__init__()
5 class B(object):
6 def __init__(self):
7 print "B"
8 super(B,self).__init__()
9 class C(A):
10 def __init__(self,arg):
11 print "c","arg=",arg
12 super(C,self).__init__()
13 class D(B):
14 def __init__(self,arg):
15 print "D","arg=",arg
16 super(D,self).__init__()
17
18 class E(C,D):
19 def __init__(self,arg):
20 print "E","arg=",arg
21 super(E,self).__init__(arg)
22 E(1)
期望输出:
E arg=1
C arg=1
A
D arg=1
E
实际输出
E arg= 10
c arg= 10
A
Traceback (most recent call last):
File "super_test.py", line 22, in <module>
E(10)
File "super_test.py", line 21, in __init__
super(E,self).__init__(arg)
File "super_test.py", line 12, in __init__
super(C,self).__init__()
File "super_test.py", line 4, in __init__
super(A,self).__init__()
TypeError: __init__() takes exactly 2 arguments (1 given)
首先 MRO顺序为E C A D B
调用继续到A.__init__时,我们调用了super(A,self).__init__,其实
调用了mro中下一个类型的方法,也就是
D中的__init__,由于D的 __init__带有1个参数,所以报错
所以如果要解决参数匹配的问题,建议采用*arg,**kwargs作为参数,所有的类也都采用super