Python 对象复制的坑:浅拷贝 vs 深拷贝
在 Python 开发中,我们常常希望复制一个对象,以避免直接修改原始数据。然而,“复制”这个操作远没有看起来那么简单。Python 提供了两种常见的复制方式:浅拷贝(shallow copy)和 深拷贝(deep copy),它们在处理嵌套对象时行为大不相同。
这篇博客会一步步解释它们之间的区别、使用场景,以及如何避免常见的坑。
赋值 ≠ 复制
先看一个简单例子:
a = [1, 2, 3] |
这里的 b = a
并没有复制 a,而是使 b 指向 a 的同一个内存地址,两者是同一个对象。
浅拷贝 (shallow copy)
import copy |
浅拷贝特点
创建了一个新对象,但只复制了第一层结构
内部嵌套对象仍然引用原始对象
修改嵌套部分,原始对象会受到影响
常用于简单结构或不打算修改嵌套部分的场景
深拷贝 (deep copy)
import copy |
深拷贝特点
递归复制所有层级的对象,生成完全独立的新对象
原始对象和复制对象互不影响
安全但性能较慢,适用于复杂对象
常用于保存快照、传递副本或避免副作用时
实战示例:字典中的 copy
original = {"user": "Alice", "settings": {"theme": "dark"}} |
虽然 shallow
是新对象,但它里面的 settings
字典依然与 original
共享,因此修改会同步到原始对象。
使用建议:如何判断用哪种?
拷贝类型 | 是否递归 | 嵌套对象独立性 | 推荐场景 |
---|---|---|---|
浅拷贝 | 否 | 否 | 简单结构、追求效率 |
深拷贝 | 是 | 是 | 嵌套结构、追求安全 |
判断建议:
- 如果你确定不会修改嵌套内容:✅ 用浅拷贝
- 如果你要修改副本、保护原始数据:✅ 用深拷贝
- 如果你的对象非常复杂(如嵌套 dict / list / 自定义类):✅ 推荐深拷贝
常见误区
- 误以为
=
是复制:它只是引用 - 误以为
copy.copy
是完全独立副本:嵌套部分仍共享 - 过度使用深拷贝:虽然安全,但会牺牲性能,特别是在大型数据结构中
总结
- 拷贝是避免副作用的重要手段,但要选对工具
- 浅拷贝只复制第一层结构,适合简单对象
- 深拷贝递归复制全部内容,适合复杂场景
- 使用
copy.copy()
和copy.deepcopy()
要清楚你的数据结构
参考内容:
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 SunnyALion!
评论