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

界面总结:

copy.copy(x)
返回x的浅表副本。
copy.deepcopy(x[memo])
返回x的深层副本。
exception copy.error
针对模块特定错误引发。

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

  • 浅拷贝构造一个新的复合对象,然后(在可能的范围内)向其中插入对原始对象中找到的对象的引用。
  • 深拷贝构造一个新的复合对象,然后递归地将在原始对象中找到的对象的副本插入其中。

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

  • 递归对象(直接或间接包含对自身的引用的复合对象)可能会导致递归循环。
  • 因为深拷贝复制了它可能复制太多的所有东西,比如打算在副本之间共享的数据。

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

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

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

字典的浅拷贝可以使用 dict.copy() 进行,列表的浅拷贝可以通过分配整个列表的一部分来进行,例如,copied_list = original_list[:]。

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

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

也可以看看

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