浅拷贝只复制顶层对象,嵌套可变对象仍共享内存;深拷贝递归复制所有层级,完全隔离。dict.copy()是浅拷贝,修改嵌套项会影响原字典;性能敏感或含特殊对象时应避免深拷贝。

浅拷贝只复制顶层,嵌套对象仍共享
浅拷贝(如 copy.copy() 或切片 [:])会创建新对象,但只复制最外层结构。如果原对象包含列表、字典、自定义类实例等可变嵌套对象,这些嵌套对象的引用会被直接复用——也就是说,新旧对象指向同一块内存地址。
例如:
import copy original = [[1, 2], [3, 4]] shallow = copy.copy(original) shallow[0].append(99) # 修改嵌套列表 print(original) # [[1, 2, 99], [3, 4]] ← 原对象也被改了!
深拷贝递归复制所有层级,彻底隔离
深拷贝(copy.deepcopy())会递归遍历整个对象树,为每个子对象都新建一份独立副本。原始对象和深拷贝后的对象完全无关,修改任一者都不会影响另一个。
继续上面的例子:
立即学习“Python免费学习笔记(深入)”;
import copy original = [[1, 2], [3, 4]] deep = copy.deepcopy(original) deep[0].append(99) print(original) # [[1, 2], [3, 4]] ← 完全不受影响 print(deep) # [[1, 2, 99], [3, 4]]
注意:深拷贝性能开销大,尤其对深层嵌套或含大量数据的对象;且无法拷贝某些特殊对象(如文件句柄、线程锁、lambda 函数等),会抛出 TypeError。
面试真题还原:为什么 dict.copy() 不是深拷贝?
候选人被问:“用 d2 = d1.copy() 复制字典后,修改 d2['items'][0],为什么 d1 也变了?”
- 原因:dict.copy() 是浅拷贝,只复制字典本身,不处理 value 中的可变对象
- 验证方式:用 id(d1['items']) == id(d2['items']) 可确认它们指向同一列表
- 正确解法:改用 copy.deepcopy(d1);或手动重建嵌套结构(如 {k: v[:] if isinstance(v, list) else v for k, v in d1.items()})
实战建议:什么情况该用哪个?
- 只有一层不可变数据(如 [1, 'a', True])→ 浅拷贝足够,速度快
- 含嵌套列表/字典/自定义类 → 必须用 deepcopy,除非你明确想共享子对象
- 性能敏感场景(如高频循环中拷贝大数据)→ 优先考虑是否真的需要拷贝,或改用不可变数据结构(tuple, frozenset, dataclass(frozen=True))
- 涉及函数、模块、IO 对象等 → 深拷贝会失败,应避免拷贝,改用依赖注入或工厂函数重新生成










