子类继承父类时,变量相互影响
来源:4-5 类变量和实例变量

慕标1049315
2021-12-03
老师,我这边写了个测试例子。但意外发现一个现象。想在子类中调用父类方法。但是有一个实例变量在子类和父类中相互影响(操作的是同一个对象)。请问老师,该怎么解释和避免这种现象呢?
class Father:
love = True
def __init__(self, wealth):
self.wealth = wealth
def give(self):
self.wealth -= 100
return 100
class Son(Father):
def __init__(self, wealth):
self.wealth = wealth
super().__init__(wealth=100)
def buy_house(self):
get = super().give()
print('爸爸给了我{}万'.format(get))
self.wealth += get
house_price = 120
self.wealth -= house_price
if __name__ == "__main__":
s = Son(20)
s.buy_house()
print('买完房后,我的余额{}'.format(s.wealth))```
写回答
2回答
-
bobby
2021-12-11
在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来初始化父类属性。
012021-12-14 -
bobby
2021-12-04
self.wealth += get
执行完以后 wealth = 100
self.wealth -= house_price
执行完以后是 -20 这里没有看出来有什么问题啊
012021-12-07
相似问题
类属性和实例属性互相影响
回答 1
元类和继承
回答 1