Python 对象克隆详解
在 Python 中,“克隆”通常指的是创建现有对象的副本,由于 Python 的变量实际上是对对象的引用,直接使用赋值符号 并不会创建新对象,而只是创建了一个指向同一内存地址的新引用。
为了实现真正的克隆,我们需要根据对象的复杂程度选择浅拷贝(Shallow Copy)或深拷贝(Deep Copy)。
引用赋值(非克隆)
当你使用 a = b 时,并没有发生克隆,两个变量指向的是同一个对象,修改其中一个,另一个也会随之改变。
- 特点:不创建新对象,仅增加引用计数。
- 适用场景:仅需起个别名时。
浅拷贝 (Shallow Copy)
浅拷贝会创建一个新对象,但如果原对象内部包含其他可变对象(如列表中的列表),它只会拷贝这些内部对象的引用。
实现方法
- 使用
copy模块:copy.copy() - 使用切片(仅限列表):
new_list = old_list[:] -
使用工厂函数
:new_list = list(old_list)或new_dict = dict(old_dict) - 使用内置方法:
new_list = old_list.copy()
关键特性
- 第一层独立:修改克隆后的顶层元素不会影响原对象。
- 嵌套层共享:修改克隆对象内部的嵌套可变对象,原对象会被同步修改。
深拷贝 (Deep Copy)
深拷贝会递归地复制对象及其包含的所有子对象,它会创建一个完全独立的副本,原对象与新对象之间没有任何共享的内存地址。
实现方法
- 使用
copy模块:copy.deepcopy()
关键特性
- 完全独立:无论对象嵌套多少层,修改新对象都不会影响原对象。
- 性能开销:由于需要递归遍历并复制所有内容,深拷贝比浅拷贝慢且占用更多内存。
核心对比总结
| 方式 | 语法 |
顶层对象 | 嵌套对象 | 独立程度 |
|---|---|---|---|---|
| 引用赋值 | b = a | 共享 | 共享 | 完全不独立 |
| 浅拷贝 | copy.copy(a) | 创建新对象 | 共享 | 部分独立 |
| 深拷贝 | copy.deepcopy(a) | 创建新对象 | 创建新对象 | 完全独立 |
代码示例演示
import copy# 准备一个嵌套列表original = [[1, 2], [3, 4]]# 1. 引用赋值ref_copy = original# 2. 浅拷贝shallow_copy = copy.copy(original) # 3. 深拷贝 deep_copy = copy.deepcopy(original) # 修改嵌套元素 original[0][0] = 'X' print(f"原对象: {original}") # [['X', 2], [3, 4]] print(f"引用赋值: {ref_copy}") # [['X', 2], [3, 4]] -> 受影响 print(f"浅拷贝: {shallow_copy}") # [['X', 2], [3, 4]] -> 受影响 (因为嵌套对象是共享的) print(f"深拷贝: {deep_copy}") # [[1, 2], [3, 4]] -> 不受影响 (完全独立) # 修改顶层元素 original.append([5, 6]) print(f"原对象: {original}") # [['X', 2], [3, 4], [5, 6]] print(f"浅拷贝: {shallow_copy}") # [['X', 2], [3, 4]] -> 不受影响 (顶层已独立)
选择指南
- 如果对象是不可变类型(如数字、字符串、元组),直接赋值即可,因为它们无法被修改。
- 如果对象是简单的一层可变类型(如简单的列表或字典),使用浅拷贝。
- 如果对象包含复杂的嵌套结构(如列表嵌套字典,或自定义类的实例),且需要确保修改副本不影响原件,必须使用深拷贝。
首发原创文章,作者:世雄 - 原生数据库架构专家,如若转载,请注明出处:https://idctop.com/article/493602.html



