Python中copy() 函数浅拷贝与深拷贝示例详解
作者:Geoking.
Python的copy()函数是copy模块提供的一个用于创建对象浅拷贝的工具,这篇文章主要介绍了Python中copy()函数浅拷贝与深拷贝的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
前言
在 Python 编程中,对象的拷贝(复制) 是一个常见又容易被忽视的概念。很多初学者在使用 copy() 时,常常会遇到修改一个对象导致另一个对象也被改变的“奇怪现象”。本文将深入理解 Python 的 copy() 函数、浅拷贝与深拷贝的区别,并通过示例让你彻底搞清楚它们的原理。
一、为什么需要拷贝对象?
当你在 Python 中使用赋值语句时,例如:
a = [1, 2, 3] b = a
此时,a 和 b指向同一个对象。这意味着修改 b 也会影响 a:
b.append(4) print(a) # 输出:[1, 2, 3, 4] print(b) # 输出:[1, 2, 3, 4]

这往往不是我们想要的结果。
如果希望创建一个“新的对象”,而不是仅仅复制引用,这时就需要用到 拷贝函数。
二、copy模块简介
Python 标准库提供了一个专门用于复制对象的模块:copy。
该模块中有两个重要函数:
copy.copy(x)—— 执行 浅拷贝copy.deepcopy(x)—— 执行 深拷贝
我们先来看看浅拷贝。
三、浅拷贝 (copy.copy())
浅拷贝会创建一个新的对象,但不会递归地复制内部的可变对象。
示例:
import copy list_a = [1, [2, 3], 4] list_b = copy.copy(list_a) print(list_a == list_b) # True,内容相同 print(list_a is list_b) # False,指向不同对象
修改外层列表时,互不影响:
list_b.append(5) print(list_a) # [1, [2, 3], 4] print(list_b) # [1, [2, 3], 4, 5]
但修改内部的可变对象时,浅拷贝仍然会“联动”:
list_b[1].append(99) print(list_a) # [1, [2, 3, 99], 4] print(list_b) # [1, [2, 3, 99], 4, 5]
✅ 结论:浅拷贝只复制最外层容器,内部元素仍然是原对象的引用。
四、深拷贝 (copy.deepcopy())
深拷贝则会递归地复制所有对象,生成完全独立的一份副本。
import copy list_a = [1, [2, 3], 4] list_b = copy.deepcopy(list_a) list_b[1].append(99) print(list_a) # [1, [2, 3], 4] print(list_b) # [1, [2, 3, 99], 4]
✅ 结论:深拷贝创建了一个完全独立的对象副本,任何修改都不会相互影响。
五、不同数据类型的拷贝行为
| 数据类型 | 浅拷贝结果 | 深拷贝结果 |
|---|---|---|
int, float, str, bool | 不可变对象,直接共享 | 相同效果 |
list, dict, set | 复制容器,但内部引用相同 | 完全独立副本 |
tuple | 如果内部包含可变对象,浅拷贝仍共享引用 | 内部对象独立 |
| 自定义类对象 | 可自定义 __copy__ / __deepcopy__ 方法 | 可完全控制复制逻辑 |
六、自定义类的拷贝行为
Python 允许开发者通过实现特殊方法 __copy__ 和 __deepcopy__ 来控制类的复制方式。
示例:
import copy
class Person:
def __init__(self, name, hobbies):
self.name = name
self.hobbies = hobbies
def __copy__(self):
print("调用浅拷贝")
return type(self)(self.name, self.hobbies)
def __deepcopy__(self, memo):
print("调用深拷贝")
new_person = type(self)(self.name, copy.deepcopy(self.hobbies, memo))
return new_person
p1 = Person("Alice", ["reading", "coding"])
p2 = copy.copy(p1)
p3 = copy.deepcopy(p1)
七、常见坑点总结
- 浅拷贝不会递归复制内部对象
a = [[1, 2], [3, 4]] b = copy.copy(a) b[0].append(99) print(a) # [[1, 2, 99], [3, 4]]
- 不可变对象(如 int, str, tuple)无需担心浅拷贝问题
a = (1, 2, 3) b = copy.copy(a) print(a is b) # True
- 深拷贝性能开销较大
深拷贝会递归复制所有内容,对于嵌套层级深或对象复杂的结构,速度会明显变慢。
如果不需要完全隔离,优先使用浅拷贝。
八、总结
| 概念 | 是否创建新对象 | 是否递归复制 | 适用场景 |
|---|---|---|---|
赋值(=) | 否 | 否 | 两变量共享同一对象 |
浅拷贝(copy.copy()) | 是 | 否 | 仅需复制一层结构 |
深拷贝(copy.deepcopy()) | 是 | 是 | 需要完全独立的副本 |
九、实践建议
- 若仅修改外层容器,用
copy.copy()即可。 - 若修改嵌套结构(如列表中包含列表),用
copy.deepcopy()。 - 若对象复杂,考虑自行实现
__copy__与__deepcopy__,以提升性能与控制力。
✨ 浅拷贝复制外壳,深拷贝复制灵魂。
到此这篇关于Python中copy() 函数浅拷贝与深拷贝的文章就介绍到这了,更多相关Python中copy()函数浅拷贝深拷贝内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
