8.10. copy - 浅和深复制操作

源代码: Lib/copy.py

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

接口概要:

copy.copy(x)

返回x的浅拷贝。

copy.deepcopy(x)

返回x的深度副本。

exception copy.error

引发模块特定错误。

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

  • 浅拷贝构建一个新的复合对象,然后(尽可能地)将原始对象中引用插入到新对象中。
  • 深拷贝构造一个新的复合对象,然后递归地把包含原始对象中找到的对象的副本插入到新对象中。

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

  • 递归对象(直接或间接包含对自身引用的复合对象)可能导致递归循环。
  • 因为深拷贝一切它可能拷贝太多,例如甚至应该在拷贝之间共享的管理数据结构。

deepcopy()函数通过以下方式避免了这些问题:

  • 保持在当前复制过程中已经复制的对象的“备忘录”字典;和
  • 让用户定义的类覆盖复制操作或复制的组件集。

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

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

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

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

也可以看看

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