Python中数据拷贝需区分浅拷贝与深拷贝:浅拷贝仅复制顶层对象,嵌套子对象仍共享引用;深拷贝递归复制所有层级,完全独立。常用方法分别为copy.copy()和copy.deepcopy()。

Python中数据拷贝不是简单赋值,直接用等号(=)只是创建新引用,原对象和副本指向同一内存地址。真正复制需要浅拷贝或深拷贝,二者核心区别在于:浅拷贝只复制最外层对象,嵌套的子对象仍共享;深拷贝递归复制所有层级,完全独立。
什么是浅拷贝?
浅拷贝生成一个新对象,但只复制顶层元素。如果原对象包含可变类型(如列表、字典、自定义类实例),这些嵌套对象在副本中仍是原对象的引用。
- 常用方法:copy.copy()、list.copy()、dict.copy()、切片 [:]
- 适用场景:对象结构扁平,或确认嵌套部分不会被修改
- 例子:
import copy
a = [1, [2, 3]]
b = copy.copy(a) # 浅拷贝
b[0] = 99 # 修改顶层 → a 不变
b[1].append(4) # 修改嵌套列表 → a[1] 也变成 [2, 3, 4]
什么是深拷贝?
深拷贝递归遍历整个对象树,为每个子对象都创建独立副本。修改副本任意层级,都不会影响原始对象。
- 唯一标准方法:copy.deepcopy()
- 适用场景:含多层嵌套、需彻底隔离的结构(如配置字典、树形数据、类实例含可变属性)
- 注意点:
- 性能开销明显更大,尤其对大型嵌套结构
- 不支持某些内置对象(如文件句柄、线程锁)和自定义类若未正确定义 __getstate__ 或 __reduce__
- 遇到循环引用时仍能安全处理(自动记录已拷贝对象)
如何选择拷贝方式?
关键看数据结构是否嵌套,以及后续是否要修改内部可变对象。
立即学习“Python免费学习笔记(深入)”;
- 纯不可变对象(如 [1, 2, 'abc'])→ 浅拷贝足够,甚至切片更轻量
- 含嵌套列表/字典(如 {'users': [{'name': 'A'}, {'name': 'B'}]})→ 必须用 deepcopy,否则改用户信息会误影响原数据
- 不确定结构深度或需绝对安全 → 直接用 deepcopy,避免隐性bug
- 性能敏感且结构可控 → 浅拷贝 + 手动处理关键嵌套项(例如单独对子列表再 deepcopy)
自定义类的拷贝行为
默认情况下,copy.copy 和 copy.deepcopy 会调用类的 __copy__ 和 __deepcopy__ 方法(如果定义了)。没定义则按默认规则处理:浅拷贝新建实例并逐字段赋值;深拷贝对每个字段递归调用 deepcopy。
- 建议:若类含可变属性(如 list/dict 类型字段),显式实现 __deepcopy__ 更可靠
- 示例片段:
def __deepcopy__(self, memo):
new_obj = MyClass()
new_obj.data = copy.deepcopy(self.data, memo) # 关键字段深拷
return new_obj










