On this page
8.17. 复制-浅复制和深复制操作
Python 中的赋值语句不复制对象,它们在目标和对象之间创建绑定。对于可变或包含可变项的集合,有时需要一个副本,因此一个副本可以更改一个副本而无需更改另一个副本。此模块提供通用的浅层和深层复制操作(如下所述)。
Interface summary:
copy.
copy
(* x *)- 返回* x *的浅表副本。
copy.
deepcopy
(* x *)- 返回* x *的深层副本。
exception
copy.
error
- 因模块特定错误而提出。
浅复制和深复制之间的区别仅与复合对象(包含其他对象的对象,如列表或类实例)有关:
“浅拷贝”将构造一个新的复合对象,然后(在可能的范围内)将“引用” *插入到原始对象中。
深拷贝构造一个新的复合对象,然后递归地将副本插入到原始对象中的对象中。
深层复制操作通常存在两个问题,浅层复制操作通常不存在两个问题:
递归对象(直接或间接包含对自己的引用的复合对象)可能会导致递归循环。
由于深层复制会复制所有内容,因此可能会复制过多,例如打算在副本之间共享的数据。
deepcopy()函数pass以下方式避免了这些问题:
保留在当前复制过程中已复制的对象的“备忘录”字典;和
让用户定义的类覆盖复制操作或复制的组件集。
该模块不复制诸如模块,方法,堆栈跟踪,堆栈框架,文件,套接字,窗口,数组或任何类似类型的类型。它pass不变地返回原始对象来“复制”函数和类(浅层和深层)。这与pickle模块处理这些内容的方式兼容。
可以使用dict.copy()来创建字典的浅表副本,也可以pass分配整个列表的一部分(例如copied_list = original_list[:]
)来创建列表的浅表副本。
在版本 2.5 中进行了更改:添加了复制Function。
类可以使用与控制 Pickling 相同的接口来控制复制。有关这些方法的信息,请参见模块pickle的描述。 copy模块不使用copy_reg注册模块。
为了让一个类定义自己的副本实现,它可以定义特殊的方法__copy__()
和__deepcopy__()
。前者被称为实现浅拷贝操作;没有传递其他参数。后者被称为实现深度复制操作。它传递了一个参数,即备忘字典。如果__deepcopy__()
实现需要复制组件的深层副本,则应调用deepcopy()函数,并将该组件作为第一个参数,并将备注字典作为第二个参数。
See also
Module pickle
讨论用于支持对象状态检索和恢复的特殊方法。