Python深拷贝与浅拷贝:copy模块详解
Python深拷贝与浅拷贝copy模块详解 ## 引言 在Python编程中对象的赋值、拷贝是不可避免的操作。但许多开发者都曾遇到过这样的困惑为什么修改拷贝后的对象原始对象也跟着变了这背后正是浅拷贝与深拷贝的区别。理解这两种拷贝机制不仅能帮你避免难以追踪的bug还能让你在处理复杂数据结构时更加得心应手。 --- ## 一、赋值 vs 拷贝本质区别 ### 1.1 赋值操作 python # 赋值只是创建新的引用 list1 [1, 2, [3, 4]] list2 list1 print(list1 is list2) # True同一对象 list2.append(5) print(list1) # [1, 2, [3, 4], 5] - list1也被修改了 **赋值只是增加了一个指向同一内存地址的引用**修改任何一个都会影响另一个。 --- ## 二、浅拷贝Shallow Copy ### 2.1 什么是浅拷贝 浅拷贝创建一个新对象然后将原对象中的**非容器类型元素**复制到新对象。但对于**容器类型元素**列表、字典等只是复制引用。 ### 2.2 创建浅拷贝的方式 python import copy # 方式1使用copy模块 original [1, 2, [3, 4]] shallow copy.copy(original) # 方式2使用切片仅限序列 shallow2 original[:] # 方式3使用list()/dict()构造函数 shallow3 list(original) print(original is shallow) # False不同对象 print(original[2] is shallow[2]) # True内部列表共享 ### 2.3 浅拷贝的行为特征 python import copy data [1, 2, [3, 4, 5]] shallow_copy copy.copy(data) # 修改不可变元素数字、字符串等 shallow_copy[0] 100 print(foriginal: {data}) # [1, 2, [3, 4, 5]] - 不变 print(fshallow: {shallow_copy}) # [100, 2, [3, 4, 5]] - 变了 # 修改嵌套的可变对象 shallow_copy[2].append(6) print(foriginal: {data}) # [1, 2, [3, 4, 5, 6]] - 也被改了 print(fshallow: {shallow_copy}) # [100, 2, [3, 4, 5, 6]] **关键结论**浅拷贝只拷贝最外层内部嵌套的可变对象仍是共享引用。 --- ## 三、深拷贝Deep Copy ### 3.1 什么是深拷贝 深拷贝创建一个新对象并**递归地复制**原对象中所有的嵌套对象。新旧对象完全独立互不影响。 ### 3.2 使用copy.deepcopy() python import copy original [1, 2, [3, 4, [5, 6]]] deep copy.deepcopy(original) print(original is deep) # False print(original[2] is deep[2]) # False print(original[2][2] is deep[2][2]) # False - 所有层级都是新对象 # 任意修改都不会影响原对象 deep[2].append(100) deep[2][2].append(200) print(foriginal: {original}) # [1, 2, [3, 4, [5, 6]]] - 完全不变 print(fdeep: {deep}) # [1, 2, [3, 4, [5, 6, 200], 100]] --- ## 四、实战对比浅拷贝 vs 深拷贝 python import copy def demonstrate_copy_differences(): original { name: 张三, scores: [85, 90, 78], info: { age: 25, hobbies: [阅读, 编程] } } shallow copy.copy(original) deep copy.deepcopy(original) shallow[scores].append(95) shallow[info][age] 26 deep[scores].append(100) deep[info][hobbies].append(运动) print(f原始数据: {original}) print(f深拷贝后: {deep}) demonstrate_copy_differences() --- ## 五、性能考量与最佳实践 ### 5.1 如何选择 | 场景 | 推荐方式 | 原因 | |------|---------|------| | 只有不可变元素 | 赋值 | 无需拷贝节省内存 | | 一层可变对象无嵌套 | copy.copy() | 快速且安全 | | 多层嵌套结构 | copy.deepcopy() | 完全隔离避免副作用 | ### 5.2 自定义类的拷贝控制 python import copy class Person: def __init__(self, name, friends): self.name name self.friends friends def __copy__(self): return Person(self.name, self.friends) def __deepcopy__(self, memo): return Person( copy.deepcopy(self.name, memo), copy.deepcopy(self.friends, memo) ) --- ## 六、常见陷阱与解决方案 ### 陷阱1误以为切片是深拷贝 python matrix [[1, 2], [3, 4]] new_matrix matrix[:] # 这是浅拷贝 new_matrix[0][0] 100 print(matrix) # [[100, 2], [3, 4]] - 原矩阵被修改 --- ## 总结 | 特性 | 赋值 () | 浅拷贝 | 深拷贝 | |------|---------|--------|--------| | 新对象 | ❌ | ✅ | ✅ | | 嵌套对象 | 共享 | 共享 | 独立 | | 性能 | 最快 | 快 | 较慢 | **核心口诀**赋值是贴标签浅拷贝是打包深拷贝是克隆。 --- ## 参考资料 1. [Python官方文档 - copy模块](https://docs.python.org/zh-cn/3/library/copy.html) 2. 《流畅的Python》第8章 - 对象引用、可变性和垃圾回收 3. [Real Python - Shallow vs Deep Copying](https://realpython.com/copying-python-objects/) --- *本文发表于 2026年3月基于 Python 3.8 编写。*