deepcopy 和 copy 本身不会影响原始数据,所谓“影响”实为修改了拷贝对象中与原对象共享的子对象;copy.copy() 仅复制外层容器,内嵌可变对象仍共享引用,修改其内容会联动原数据;deepcopy 虽递归复制全部层级,但自引用、序列化逻辑错误或误覆盖变量可能导致误判;不可变对象拷贝时直接复用内存地址,无联动风险。

deepcopy 和 copy 本身不会影响原始数据——但你观察到的“影响”,其实是修改了拷贝后对象里的共享子对象,而那个子对象恰好也被原始数据引用着。
真正出问题的地方,从来不是拷贝函数本身,而是你没意识到哪些东西被共享了。
copy.copy() 修改嵌套可变对象时会联动原始数据
copy.copy() 只新建外层容器(比如新列表),内部元素仍是原对象的引用。
一旦这些元素是可变对象(如子列表、子字典),改它们就等于直接改内存里同一块数据。
常见错误现象:
shallow[2][0] = 99后,original[2]也变成[99, 4]使用场景:
适合只读外层结构、或确认内部没有可变嵌套的场景(比如纯数字列表)-
容易踩的坑:
立即学习“Python免费学习笔记(深入)”;
- 把
list.copy()或切片[:]当成“完全隔离”,忽略了内层引用 - 对字典做
dict.copy()后修改new_dict['config']['timeout'],结果老字典也变了 - 元组里包着列表?浅拷贝后元组不变,但列表仍共享 → 改列表照样联动
- 把
copy.deepcopy() 为什么有时也“看起来”影响了原始数据?
它本身绝不会影响原始数据。但以下情况会让你误判:
原始对象里有自引用或循环引用(比如
a = [1, 2]; a.append(a)):deepcopy能正确处理,但调试时打印可能显示混乱结构,让人以为“串了”拷贝过程中触发了对象的
<strong>reduce</strong>或<strong>getstate</strong>:
如果自定义类没正确定义序列化逻辑,deepcopy可能复用旧实例或调用意外方法你其实没在操作拷贝结果,而是在反复对同一个变量赋值:
data = copy.deepcopy(data)—— 这不是拷贝,这是覆盖,原始引用早丢了性能代价真实存在:
deepcopy递归遍历所有属性,遇到大嵌套结构(如含千级嵌套的配置字典)会明显卡顿,还可能爆栈(除非手动设sys.setrecursionlimit)
不可变对象在拷贝中根本不用操心
字符串、整数、元组(不含可变项)这类对象,Python 会直接复用对象地址:
-
id(copy.copy("hello")) == id("hello")→True -
id(copy.deepcopy((1, 2))) == id((1, 2))→True
所以只要你没往元组里塞列表或字典,就不存在“联动修改”这回事。
关键不在函数名,而在你操作的是哪一层。
很多人盯着 copy 和 deepcopy 看半天,却忘了检查自己真正改的那一行代码:到底是改了顶层索引,还是钻进了 [2][0][1] 这种三级嵌套里。


















