类实例循环中数值属性a被重置但列表属性b未清空的原因及解决办法
问题解析与解决
为什么a和b表现不同?
你定义的a=5和b=[]是类属性,属于整个bag类,所有实例默认共享。但因为数据类型的可变性不同,导致操作后的行为完全不一样:
对于不可变类型(比如整数a):
执行self.a = self.a + 1时,整数是不可修改的对象,self.a +1会生成一个新的整数6,然后把这个值赋值给self.a——这一步会给当前实例创建一个专属的实例属性a,直接覆盖掉类属性的a。所以每次循环新建实例时,类属性a还是初始的5,实例调用funcie时,先读取类属性的5,加1后赋值给自己的实例属性a,因此每次输出都是6。对于可变类型(比如列表b):
执行self.b.append(1)时,列表是可变对象,append是直接在原列表上做修改,并没有给实例创建新的属性b。也就是说,所有实例操作的都是同一个类属性的列表,所以每次循环都会往这个共享列表里加元素,导致b持续累加。
如何让b每次循环后清空?
要让每个实例拥有独立的a和b,需要在类的__init__方法里初始化实例属性,而不是依赖类属性:
class bag: def __init__(self): self.a = 5 # 每个实例初始化自己的a self.b = [] # 每个实例初始化自己的空列表 def funcie(self): self.a = self.a + 1 self.b.append(1) for i in range(5): inst = bag() inst.funcie() print(inst.a) print(inst.b)
修改后的输出会变成:
6 [1] 6 [1] 6 [1] 6 [1] 6 [1]
每个实例的b都是专属的空列表,调用funcie后只会添加一个1,循环结束后实例被销毁,下次循环新建的实例会重新初始化空列表。
内容的提问来源于stack exchange,提问作者Daan
相关产品推荐
相关产品推荐

