Python类初始化空列表默认值内存地址相同问题解惑
为什么FirstClass与SecondClass的行为不同?
我希望初始化同一类的多个实例,每个实例拥有一个初始为空的列表属性,后续在脚本中向该列表添加元素。但遇到问题:这些空列表的内存地址完全相同。
例如,定义如下类并创建两个实例:
class FirstClass: def __init__(self, values=[]): self.values = values a = FirstClass() b = FirstClass()
当我向b.values中添加元素时:
b.values += ['boat'] print(a.values) # 输出 ['boat'] # 另外: print(a.values is b.values) # 输出 True
而以下写法解决了该问题:
class SecondClass: def __init__(self, values=None): self.values = values if values is not None else [] A = SecondClass() B = SecondClass() print(A.values is B.values) # 输出 False
核心原因:Python默认参数的绑定时机
FirstClass的问题根源
Python的默认参数是在函数定义时就创建并绑定的,而非每次调用函数(实例化类)时重新生成。
对于FirstClass的__init__方法,默认参数values=[]在类定义阶段就创建了一个空列表对象。之后每次实例化FirstClass时,都会直接复用这个预先存在的列表——所有实例的self.values都指向同一个内存地址的列表对象。
因此修改b.values本质是修改这个共享列表,a.values也会同步变化,is判断返回True也验证了它们是同一个对象。
SecondClass的解决方案逻辑
SecondClass将默认参数设为None,然后在__init__方法内部做判断:如果传入的values是None,就在每次实例化时新建一个空列表。
这样每次调用SecondClass()时,都会生成一个全新的空列表,每个实例的self.values指向各自独立的列表,不会出现跨实例的修改影响,is判断返回False也说明它们是不同的对象。
内容的提问来源于stack exchange,提问作者Arkeor
相关产品推荐
相关产品推荐

