copy ——浅拷贝和深拷贝操作

源代码: Lib/copy.py


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

接口摘要:

copy.copy(x)

返回 x .

copy.deepcopy(x[, memo])

返回的深度副本 x .

exception copy.error

针对模块特定错误引发。

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

  • A 浅拷贝 构造新的复合对象,然后(尽可能)插入 参考文献 把它放进原图中找到的对象。

  • A 深拷贝 构造一个新的复合对象,然后递归地插入 副本 在它里面找到了原始的物体。

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

  • 递归对象(直接或间接包含对自身引用的复合对象)可能导致递归循环。

  • 因为深度复制会复制所有可能复制过多的内容,例如打算在副本之间共享的数据。

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

  • 保持一个 memo 当前复制过程中已复制对象的字典;以及

  • 让用户定义的类重写复制操作或复制的组件集。

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

可以使用 dict.copy() 例如,通过分配整个列表的一个切片, copied_list = original_list[:] .

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

为了让类定义自己的复制实现,它可以定义特殊的方法 __copy__()__deepcopy__() . 调用前者以实现浅复制操作;不传递其他参数。后者被调用来实现深度复制操作;它被传递一个参数,即 memo 字典。如果 __deepcopy__() 实现需要对组件进行深度复制,它应该调用 deepcopy() 函数的第一个参数是组件,第二个参数是memo字典。备忘录字典应该被视为一个不透明的对象。

参见

模块 pickle

讨论了支持对象状态检索和恢复的特殊方法。