← 返回首页

Python 中的浅拷贝和深拷贝的理解

在 Python 中,理解浅拷贝(Shallow Copy)和深拷贝(Deep Copy)的核心,在于理解 Python 的对象引用机制。

简单来说:

  • 浅拷贝:只复制了对象的“外壳”(第一层),内部的嵌套对象依然是引用(共享内存)。
  • 深拷贝:不仅复制了“外壳”,还递归地复制了内部所有的嵌套对象,实现了彻底的独立(完全独立的新内存)。

1. 浅拷贝(Shallow Copy)

浅拷贝会创建一个新的对象,但这个新对象内部的元素,依然是原对象中元素的引用。

  • 常见触发方式:切片操作 [:]、工厂函数 list() / dict()、copy.copy()。
  • 内存表现:外层对象是新的,但如果内部包含列表、字典等可变对象,内外两层对象会指向同一块内存。

代码示例:

import copy

original = [1, 2, [3, 4]]
shallow = copy.copy(original) # 或者 shallow = original[:]

修改外层元素(互不影响)

shallow[0] = 99
print(original) # [1, 2, [3, 4]] (不受影响)

修改内层嵌套对象(互相影响!)

shallow[2][0] = 88
print(original) # [1, 2, [88, 4]] (原数据也被修改了)

2. 深拷贝(Deep Copy)

深拷贝会创建一个完全独立的新对象。它会递归地复制原对象中的所有层级的对象。

  • 常见触发方式:copy.deepcopy()。
  • 内存表现:无论是外层还是内层嵌套对象,全部分配了全新的内存空间,与原对象彻底解绑。

代码示例:

import copy

original = [1, 2, [3, 4]]
deep = copy.deepcopy(original)

修改外层元素(互不影响)

deep[0] = 99
print(original) # [1, 2, [3, 4]] (不受影响)

修改内层嵌套对象(也互不影响!)

deep[2][0] = 88
print(original) # [1, 2, [3, 4]] (原数据完全不受影响)


3. 核心对比总结

特性 赋值 (=) 浅拷贝 (copy.copy) 深拷贝 (copy.deepcopy)
内存地址 完全相同(同一个对象) 仅第一层对象地址不同 所有层级对象地址均不同
修改外层元素 互相影响 互不影响 互不影响
修改内层嵌套对象 互相影响 互相影响 互不影响
执行开销 极低 中等 较高(需递归复制)

 实际开发建议

  1. 对于不可变对象(如纯数字、字符串、元组):浅拷贝和深拷贝没有区别,因为它们本身不能被修改,修改只会触发重新赋值。
  2. 对于一维列表/字典:使用浅拷贝(如 list.copy() 或 [:])就足够了,性能更好。
  3. 对于包含嵌套结构(如二维列表、复杂字典)且需要独立修改的场景:必须使用 copy.deepcopy(),否则极易引发难以排查的“数据污染”Bug。