copy — 浅拷贝和深拷贝操作 — Python 文档

来自菜鸟教程
Python/docs/3.8/library/copy
跳转至:导航、​搜索

copy — 浅拷贝和深拷贝操作

源代码: :source:`Lib/copy.py`



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

界面总结:

copy.copy(x)
返回 x 的浅拷贝。
copy.deepcopy(x[, memo])
返回 x 的深层副本。
exception copy.Error
为特定于模块的错误引发。

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

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

深拷贝操作通常存在两个问题,而浅拷贝操作不存在这些问题:

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

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

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

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

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

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

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

也可以看看

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