# 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`
  讨论用于支持对象状态检索和恢复的特殊方法。