← 返回首页
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) |
|---|---|---|---|
| 内存地址 | 完全相同(同一个对象) | 仅第一层对象地址不同 | 所有层级对象地址均不同 |
| 修改外层元素 | 互相影响 | 互不影响 | 互不影响 |
| 修改内层嵌套对象 | 互相影响 | 互相影响 | 互不影响 |
| 执行开销 | 极低 | 中等 | 较高(需递归复制) |
实际开发建议
- 对于不可变对象(如纯数字、字符串、元组):浅拷贝和深拷贝没有区别,因为它们本身不能被修改,修改只会触发重新赋值。
- 对于一维列表/字典:使用浅拷贝(如
list.copy()或[:])就足够了,性能更好。 - 对于包含嵌套结构(如二维列表、复杂字典)且需要独立修改的场景:必须使用
copy.deepcopy(),否则极易引发难以排查的“数据污染”Bug。