Python列表中默认构造函数创建的对象为何看似浅拷贝?
解决自定义类对象列表共享属性的问题
嘿,我太懂你碰到的这个糟心问题了!这种“改一个对象,整个列表里的对象属性全跟着变”的情况,几乎都是因为你在类里定义了类级别的共享属性,而不是每个实例独有的实例属性。
问题根源
当你在类定义里直接初始化属性(比如class MyClass: data = []),这个属性是属于整个类的,所有通过这个类创建的实例都会共享同一个属性引用。不管你用默认构造函数创建多少个对象,它们指向的都是同一个内存里的属性——就像好几个人共用同一个笔记本,你写一笔所有人都能看到。
而当你通过传入参数创建对象时,你大概率是在__init__方法里把参数赋值给了self.xxx(比如self.data = passed_data),这时候每个实例都会拥有自己独立的属性副本,自然不会互相干扰。
错误示例 vs 正确示例
错误写法(类属性导致共享)
class MyCustomClass: # 这里是类属性,所有实例共享同一份 internal_data = [] def __init__(self): # 没有初始化实例属性,默认使用类属性 pass def update_data(self, value): self.internal_data.append(value) # 创建对象列表 objects = [MyCustomClass() for _ in range(3)] # 修改第一个对象的属性 objects[0].update_data("hello") # 结果所有对象的属性都变了! print(objects[0].internal_data) # ['hello'] print(objects[1].internal_data) # ['hello'] print(objects[2].internal_data) # ['hello']
正确写法(实例属性独立)
class MyCustomClass: def __init__(self): # 这里是实例属性,每个对象创建时都会生成新的独立副本 self.internal_data = [] def update_data(self, value): self.internal_data.append(value) # 创建对象列表 objects = [MyCustomClass() for _ in range(3)] # 修改第一个对象的属性 objects[0].update_data("hello") # 只有被修改的对象属性变化,其他不受影响 print(objects[0].internal_data) # ['hello'] print(objects[1].internal_data) # [] print(objects[2].internal_data) # []
排查建议
去检查你的自定义类代码:
- 看看是不是把需要每个实例独立维护的属性,直接定义在了类的顶层(没有放在
__init__方法里的self.下) - 如果类里有可变类型的属性(比如列表、字典),一定要确保它们是在
__init__中初始化的实例属性,而不是类属性
这样就能彻底解决“所有对象属性同步变化”的问题啦!
内容的提问来源于stack exchange,提问作者Sentry
相关产品推荐
相关产品推荐

