copy
— 浅拷贝和深拷贝操作¶
源代码: Lib/copy.py
Python 中的赋值语句不会复制对象,而是创建目标和对象之间的绑定。对于可变或包含可变项的集合,有时需要复制,以便可以更改一个副本而不更改另一个副本。此模块提供通用的浅拷贝和深拷贝操作(如下所述)。
接口摘要
- copy.copy(x)¶
返回 x 的浅拷贝。
- copy.deepcopy(x[, memo])¶
返回 x 的深拷贝。
- 异常 copy.Error¶
针对模块特定错误引发。
浅拷贝和深拷贝之间的区别仅与复合对象(包含其他对象的的对象,如列表或类实例)相关。
浅拷贝 构造一个新的复合对象,然后(尽可能)将对原始对象中找到的对象的引用插入其中。
深拷贝 构造一个新的复合对象,然后递归地将原始对象中找到的对象的副本插入其中。
深拷贝操作通常存在两个浅拷贝操作不存在的问题。
递归对象(直接或间接包含对自身的引用的复合对象)可能会导致递归循环。
因为深拷贝会复制所有内容,所以它可能会复制过多内容,例如打算在副本之间共享的数据。
deepcopy()
函数通过以下方式避免了这些问题:
保留一个已在当前复制过程中复制的对象的
memo
字典;以及允许用户定义的类覆盖复制操作或复制的组件集。
此模块不复制模块、方法、堆栈跟踪、堆栈帧、文件、套接字、窗口或任何类似类型。它通过返回未更改的原始对象来“复制”函数和类(浅层和深层);这与 pickle
模块处理这些类型的方式兼容。
可以使用 dict.copy()
创建字典的浅拷贝,并通过分配整个列表的切片来创建列表的浅拷贝,例如 copied_list = original_list[:]
。
类可以使用与控制序列化相同的接口来控制复制。有关这些方法的信息,请参阅模块 pickle
的描述。实际上,copy
模块使用来自 copyreg
模块的注册序列化函数。
为了使类定义自己的复制实现,它可以定义特殊方法 __copy__()
和 __deepcopy__()
。前者被调用来实现浅拷贝操作;不传递额外的参数。后者被调用来实现深拷贝操作;它传递一个参数,即 memo
字典。如果 __deepcopy__()
实现需要对组件进行深拷贝,它应该调用 deepcopy()
函数,将组件作为第一个参数,将 memo 字典作为第二个参数。memo 字典应被视为不透明对象。
另请参阅
- 模块
pickle
讨论用于支持对象状态检索和恢复的特殊方法。