Skip to main content

8.10. copy —浅和深复制操作

源代码: Lib/copy.py


Python中的赋值语句不复制对象,它们在目标和对象之间创建绑定。对于可变的或包含可变项的集合,有时需要一个副本,所以可以改变一个副本而不改变另一个副本。此模块提供通用的浅层和深层复制操作(如下所述)。

接口总结:

copy.copy(x)

返回 x 的浅拷贝。

copy.deepcopy(x)

返回 x 的深度副本。

exception copy.error

引发模块特定错误。

浅层和深层复制之间的区别仅与复合对象(包含其他对象,如列表或类实例的对象)有关:

  • 浅拷贝 构造一个新的复合对象,然后(尽可能地)将 references 插入到原始对象中。

  • 深复制 构造新的复合对象,然后递归地将 copies 插入到原始对象中找到的对象中。

对于浅拷贝操作不存在的深拷贝操作,通常存在两个问题:

  • 递归对象(直接或间接包含对自身的引用的复合对象)可能导致递归循环。

  • 因为深拷贝复制 everything 它可能复制太多,例如甚至应该在拷贝之间共享的管理数据结构。

deepcopy() 功能通过以下方式避免这些问题:

  • 保持在当前复制过程期间已经复制的对象的“备忘录”字典;和

  • 让用户定义的类覆盖复制操作或复制的组件集。

此模块不复制像模块,方法,堆栈跟踪,堆栈框架,文件,套接字,窗口,数组或任何类似类型的类型。它通过返回原始对象不改变来“复制”函数和类(浅和深)这与 pickle 模块所处理的方式兼容。

可以使用 dict.copy() 和列表的浅拷贝来分配整个列表的片段,例如 copied_list = original_list[:]

类可以使用相同的接口来控制用于控制酸洗的复制。有关这些方法的信息,请参阅模块 pickle 的描述。事实上,copy 模块使用来自 copyreg 模块的注册pickle函数。

为了让一个类定义自己的副本实现,它可以定义特殊的方法 __copy__()__deepcopy__()。前者被称为实现浅拷贝操作;不会传递额外的参数。后者被称为实现深层复制操作;它传递一个参数,备忘录字典。如果 __deepcopy__() 实现需要做一个组件的深层副本,它应该调用 deepcopy() 函数,该组件作为第一个参数,备忘录字典作为第二个参数。

参见

模块 pickle

讨论用于支持对象状态检索和恢复的特殊方法。