为什么Python类的多个实例会共享同一个默认列表属性的值?
问题根因
你遇到的现象和类实例的逻辑无关,属于Python可变类型作为函数默认参数的经典特性:函数的默认参数只会在函数定义时初始化一次,而非每次调用函数时重新生成。如果默认参数是列表、字典这类可变对象,所有未显式传参的函数调用,都会共用同一个可变对象。
你的两个疑问解答
1. 实例b的err属性初始值为何是[0]而非空列表
- 你定义
__init__方法时,默认参数err = []就已经创建了一个全局的列表对象,所有未传入err参数初始化的C类实例,self.err都会绑定到这个相同的列表上 - 你初始化a之后调用了
a.add(),给这个公共列表追加了元素0,后续初始化b时没有传入err参数,因此b.err直接绑定的就是已经被修改过的、包含0的公共列表
2. 向b的err添加元素会同步影响a.err的原因
- a.err和b.err本质指向内存中的同一个列表对象,你对任意一个实例的err做修改,都是操作同一块内存地址的数据,修改结果自然会在两个实例上同时体现
修复方案
将默认参数改为不可变的None,每次初始化时如果未传参就新生成一个空列表,即可保证每个实例的err属性独立:
class C(): def __init__(self, err = None): self.err = err if err is not None else [] def add(self): self.err.append(0)
修改后再运行你的测试代码,各个实例的err属性就会互相独立,不会出现同步修改的问题。
内容的提问来源于stack exchange,提问作者unknown
相关产品推荐
相关产品推荐

