跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

Python深浅拷贝什么区别_copy模块与可变对象内存分析

浅拷贝只复制外层容器,嵌套可变对象仍共享引用,修改子列表会导致原对象变化;深拷贝递归复制所有层级,完全隔离,但性能开销大;不可变对象无需拷贝,Python自动共享。 浅拷贝修改嵌套列表时原对象跟着变 因为
copy.copy()
只复制最外层容器,内部可变对象(比如列表里的子列表)仍是同一份引用。改子列表,原对象就同步变化。 常见错误现象:
original = [[1, 2], [3]]; shallow = copy.copy(original); shallow[0].append(99); print(original)
→ 输出
[[1, 2, 99], [3]]
,不是预期的不变。 适用场景:只有一层结构、全是不可变元素(如
[1, 'a', True]
),或明确知道不会修改嵌套内容 性能更好:不递归遍历,开销小 注意
list.copy()
、
[:]
、
list(original)
都是浅拷贝,不是“真复制” 深拷贝能真正隔离嵌套可变对象
copy.deepcopy()
会递归复制所有层级的可变对象,确保新旧对象内存完全独立。改拷贝体,原对象绝对不受影响。 使用场景:数据结构含多层嵌套(如 JSON-like 字典、树形列表)、需要安全传递/修改副本而不污染源头。 立即学习 “ Python免费学习笔记(深入) ”; Python 3.14.3 微软官方的 Python 扩展,是 VS Code 安装量最高的扩展(209M+)。集成 IntelliSense(通过 Pylance)、调试(通过 Python Debugger)、代码检查、格式化、重构和单元测试等功能。支持 Jupyter Notebook、虚拟环境管理和多 Python 版本切换。 下载 参数无额外选项,但支持自定义
__deepcopy__
方法控制行为 性能代价明显:递归 + 检查循环引用,大数据量或深层嵌套时明显变慢 不支持无法序列化的对象(如文件句柄、线程锁),会抛
TypeError
不可变对象根本不需要拷贝 字符串、整数、元组(且内部全不可变)在 Python 中是共享引用的,
copy.copy()
或
copy.deepcopy()
对它们都返回原对象本身——因为改不了,也无需隔离。 例如:
a = (1, 2); b = copy.copy(a); a is b
返回
True
;
id(a) == id(b)
也成立。 元组含可变项(如
([],)
)则另当别论:外层不可变,但内层列表仍可被修改,此时必须用深拷贝才安全 别为提升性能刻意避免拷贝不可变对象——Python 已经帮你做了最优处理 自定义类里要小心 __dict__ 和循环引用 默认情况下
copy.deepcopy()
通过
__dict__
复制实例属性,但如果类里有函数、模块、类对象或弱引用,可能出错或行为异常。 更麻烦的是循环引用:
a = []; b = [a]; a.append(b)
这种结构,深拷贝必须检测并重建引用链,否则无限递归。 若需精确控制,实现
__copy__(self)
和
__deepcopy__(self, memo)
方法
memo
是字典,记录已拷贝对象的 id 映射,用于破循环;手动实现时务必传给子对象的
deepcopy
没重写
__deepcopy__
却含 C 扩展对象(如 NumPy 数组),可能跳过深拷贝逻辑,导致意外共享 实际用的时候,别光看“深”“浅”字面意思。关键看你的数据有没有嵌套可变对象,以及你是否打算改它。改,就用
deepcopy
;不改,或者只有一层,
copy
或切片够用。最常被忽略的是元组和自定义类——表面 immutable,里面藏了个 list,一改就穿帮。

相关文章