You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:29:30