copyShallow and deep copy operations浅拷贝和深度拷贝操作

Source code: Lib/copy.py


Assignment statements in Python do not copy objects, they create bindings between a target and an object. Python中的赋值语句不复制对象,而是在目标和对象之间创建绑定。For collections that are mutable or contain mutable items, a copy is sometimes needed so one can change one copy without changing the other. 对于可变或包含可变项的集合,有时需要一个副本,以便可以更改一个副本而不更改另一个副本。This module provides generic shallow and deep copy operations (explained below).此模块提供通用的浅拷贝和深度拷贝操作(解释如下)。

Interface summary:接口摘要:

copy.copy(x)

Return a shallow copy of x.返回x的浅拷贝。

copy.deepcopy(x[, memo])

Return a deep copy of x.返回x的深度副本。

exceptioncopy.Error

Raised for module specific errors.针对模块特定错误引发。

The difference between shallow and deep copying is only relevant for compound objects (objects that contain other objects, like lists or class instances):浅复制和深度复制之间的差异仅与复合对象(包含其他对象的对象,如列表或类实例)相关:

  • A shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original.浅层副本构造一个新的复合对象,然后(尽可能)在其中插入对原始对象的引用

  • A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original.深层副本构造一个新的复合对象,然后递归地将在原始对象中找到的对象的副本插入其中。

Two problems often exist with deep copy operations that don’t exist with shallow copy operations:深度复制操作通常存在两个问题,而浅层复制操作则不存在这两个问题:

  • Recursive objects (compound objects that, directly or indirectly, contain a reference to themselves) may cause a recursive loop.递归对象(直接或间接包含自身引用的复合对象)可能会导致递归循环。

  • Because deep copy copies everything it may copy too much, such as data which is intended to be shared between copies.因为深度复制复制了所有内容,所以它可能复制了太多内容,例如打算在副本之间共享的数据。

The deepcopy() function avoids these problems by:deepcopy()函数通过以下方式避免了这些问题:

  • keeping a memo dictionary of objects already copied during the current copying pass; and保存当前复制过程中已复制对象的memo字典;和

  • letting user-defined classes override the copying operation or the set of components copied.让用户定义的类覆盖复制操作或复制的组件集。

This module does not copy types like module, method, stack trace, stack frame, file, socket, window, or any similar types. 此模块不复制诸如模块、方法、堆栈跟踪、堆栈帧、文件、套接字、窗口或任何类似类型的类型。It does “copy” functions and classes (shallow and deeply), by returning the original object unchanged; this is compatible with the way these are treated by the pickle module.它通过原封不动地返回原始对象来“复制”函数和类(浅层和深层);这与pickle模块处理它们的方式兼容。

Shallow copies of dictionaries can be made using dict.copy(), and of lists by assigning a slice of the entire list, for example, copied_list = original_list[:].可以使用dict.copy()创建字典的浅拷贝,也可以通过分配整个列表的一部分来创建列表的浅拷贝,例如,copied_list = original_list[:]

Classes can use the same interfaces to control copying that they use to control pickling. 类可以使用与控制酸洗相同的接口来控制复制。See the description of module pickle for information on these methods. 有关这些方法的信息,请参阅模块pickle的描述。In fact, the copy module uses the registered pickle functions from the copyreg module.实际上,copy模块使用copyreg模块中注册的pickle函数。

In order for a class to define its own copy implementation, it can define special methods __copy__() and __deepcopy__(). 为了让类定义自己的复制实现,它可以定义特殊方法__copy__()__deepcopy__()The former is called to implement the shallow copy operation; no additional arguments are passed. 前者用于实现浅层复制操作;没有传递其他参数。The latter is called to implement the deep copy operation; it is passed one argument, the memo dictionary. 调用后者来实现深度复制操作;它传递了一个参数,即memo字典。If the __deepcopy__() implementation needs to make a deep copy of a component, it should call the deepcopy() function with the component as first argument and the memo dictionary as second argument. 如果__deepcopy__()实现需要对组件进行深度复制,那么它应该调用deepcopy()函数,该组件作为第一个参数,备忘录字典作为第二个参数。The memo dictionary should be treated as an opaque object.备忘录字典应视为不透明对象。

See also另请参见

Module 模块pickle

Discussion of the special methods used to support object state retrieval and restoration.讨论用于支持对象状态检索和恢复的特殊方法。