在python继承中,子类的init()方法中需要初始化父类的属性,常常会用到super(child, self).init(arg1, arg2)这样的方法。
下面思考一下如下几个问题:
1.如果在子类的构造函数中需要初始化父类的属性,一般需要使用super,是否可以使用同名的属性来进行初始化。
看几个例子:
使用self.value复制的方式:
class P(object):
def __init__(self):
self.value = 0
print "++++++"
print id(self.value)
def get(self):
print "p get"
print self.value
return id(self.value)
class C(P):
def __init__(self):
print "start"
self.value = 44 #两句交换一下位置看看
#super(C, self).__init__() #标准的写法是这样的, 先调用父类构造函数
print id(self.value)
print "======="
print id(self.value)
def get(self):
print "c get"
print self.value
return id(self.value)
def getsuper(self):
return super(C, self).get()
c = C()
print c.get()
print "----------"
print c.getsuper()
➜ ~ python object.py
start
19263528
=======
19263528
c get
44
19263528
----------
p get
44
19263528
分析结果:
从结果可以看到,父类和子类的同名成员是同一个id。
使用super方式,修改一下代码:
class P(object):
def __init__(self):
self.value = 0
print "++++++"
print id(self.value)
def get(self):
print "p get"
print self.value
return id(self.value)
class C(P):
def __init__(self):
print "start"
#self.value = 44 #两句交换一下位置看看
super(C, self).__init__() #标准的写法是这样的, 先调用父类构造函数
print id(self.value)
print "======="
print id(self.value)
def get(self):
print "c get"
print self.value
return id(self.value)
def getsuper(self):
return super(C, self).get()
c = C()
print c.get()
print "----------"
print c.getsuper()
输出结果:
➜ ~ python object.py
start
++++++
22908032
22908032
=======
22908032
c get
0
22908032
----------
p get
0
22908032
分析结果:
如果使用super来初始化父类属性,可以看到,结果是一样的。
如果有两个初始化的操作
class P(object):
def __init__(self):
self.value = 0
print "++++++"
print id(self.value)
def get(self):
print "p get"
print self.value
return id(self.value)
class C(P):
def __init__(self):
super(C, self).__init__() #标准的写法是这样的, 先调用父类构造函数
print "start"
self.value = 44 #两句交换一下位置看看
print id(self.value)
print "======="
print id(self.value)
def get(self):
print "c get"
print self.value
return id(self.value)
def getsuper(self):
return super(C, self).get()
c = C()
print c.get()
print "----------"
print c.getsuper()
输出结果:
➜ ~ python object.py
++++++
10316928
start
10317864
=======
10317864
c get
44
10317864
----------
p get
44
10317864
分析结果:
可以看出来结果有些不同,这是因为后一个初始化方法会覆盖前一个初始化方法。即self.value会覆盖super(C, self)._init_(),所以会有两个id,但是get方法得到的都是id,都是后面一个value的id。
2.为什么一般都是用super这种方式来初始化父类的属性,而不用self.value = xxx这种方式。
该例子中是因为父类的属性并不是特别多,所以并没有什么影响,如果子类需要继承的父类属性较多,可能就会比较麻烦,所以我们一般使用super来初始化父类属性。