8.10. copy — 浅拷贝和深拷贝操作 — Python 文档
来自菜鸟教程
Python/docs/3.6/library/copy
8.10. 复制 — 浅拷贝和深拷贝操作
Python 中的赋值语句不复制对象,它们在目标和对象之间创建绑定。 对于可变或包含可变项目的集合,有时需要一个副本,以便可以更改一个副本而不更改另一个。 该模块提供通用的浅拷贝和深拷贝操作(解释如下)。
界面总结:
- copy.copy(x)
- 返回 x 的浅拷贝。
- copy.deepcopy(x[, memo])
- 返回 x 的深层副本。
- exception copy.error
- 为特定于模块的错误引发。
浅拷贝和深拷贝的区别仅与复合对象(包含其他对象的对象,如列表或类实例)有关:
- 浅拷贝构造一个新的复合对象,然后(尽可能)将引用插入到原始对象中的对象中。
- 深拷贝 构造一个新的复合对象,然后递归地将原始对象中的 副本 插入其中。
深拷贝操作通常存在两个问题,而浅拷贝操作不存在这些问题:
- 递归对象(直接或间接包含对自身的引用的复合对象)可能会导致递归循环。
- 因为深拷贝会复制所有内容,所以它可能会复制太多,例如打算在副本之间共享的数据。
deepcopy() 函数通过以下方式避免了这些问题:
- 保留在当前复制过程中已经复制的对象的
memo
字典; 和 - 让用户定义的类覆盖复制操作或复制的组件集。
此模块不复制模块、方法、堆栈跟踪、堆栈帧、文件、套接字、窗口、数组或任何类似类型等类型。 它通过返回原始对象不变来“复制”函数和类(浅的和深的); 这与 pickle 模块处理这些的方式兼容。
可以使用 dict.copy() 制作字典的浅拷贝,通过分配整个列表的一个切片来制作列表,例如 copied_list = original_list[:]
。
类可以使用相同的接口来控制它们用来控制酸洗的复制。 有关这些方法的信息,请参阅模块 pickle 的说明。 事实上,copy模块使用了copyreg模块中注册的pickle函数。
为了让一个类定义自己的复制实现,它可以定义特殊的方法 __copy__()
和 __deepcopy__()
。 前者被调用来实现浅拷贝操作; 没有传递额外的参数。 调用后者实现深拷贝操作; 它传递了一个参数,即 memo
字典。 如果 __deepcopy__()
实现需要对组件进行深拷贝,它应该调用 deepcopy() 函数,将组件作为第一个参数,将备忘录字典作为第二个参数。