copy
— 浅层和深层复制操作¶
源代码: Lib/copy.py
Python 中的赋值语句不会复制对象,它们会在目标和对象之间创建绑定。对于可变或包含可变项的集合,有时需要复制,以便可以更改一个副本而不更改另一个副本。此模块提供通用的浅层和深层复制操作(如下所述)。
接口摘要
- copy.copy(obj)¶
返回 obj 的浅层副本。
- copy.deepcopy(obj[, memo])¶
返回 obj 的深层副本。
- copy.replace(obj, /, **changes)¶
创建一个与 obj 类型相同的新对象,并用 changes 中的值替换字段。
3.13 版本新增。
- exception copy.Error¶
为模块特定错误引发。
浅层复制和深层复制之间的区别仅与复合对象(包含其他对象的对象,例如列表或类实例)相关
浅层复制 构造一个新的复合对象,然后(在可能的范围内)将引用插入到原始对象中找到的对象中。
深层复制 构造一个新的复合对象,然后递归地将原始对象中找到的对象的副本插入到其中。
深层复制操作通常存在两个浅层复制操作不存在的问题
递归对象(直接或间接包含对其自身的引用的复合对象)可能会导致递归循环。
因为深层复制会复制所有内容,所以它可能会复制太多,例如打算在副本之间共享的数据。
deepcopy()
函数通过以下方式避免这些问题:
保留一个
memo
字典,其中包含当前复制过程中已复制的对象;并且允许用户定义的类重写复制操作或复制的组件集。
此模块不复制模块、方法、堆栈跟踪、堆栈帧、文件、套接字、窗口或任何类似类型。它通过返回未更改的原始对象来“复制”函数和类(浅层和深层);这与 pickle
模块处理这些对象的方式兼容。
可以使用 dict.copy()
进行字典的浅层复制,使用整个列表的切片进行列表的浅层复制,例如,copied_list = original_list[:]
。
类可以使用相同的接口来控制复制,这些接口用于控制 pickling。有关这些方法的信息,请参阅模块 pickle
的描述。实际上,copy
模块使用 copyreg
模块中注册的 pickle 函数。
为了让类定义自己的复制实现,它可以定义特殊方法 __copy__()
和 __deepcopy__()
。
- object.__copy__(self)¶
调用以实现浅层复制操作;不传递其他参数。
- object.__deepcopy__(self, memo)¶
调用以实现深层复制操作;它传递一个参数,即 memo 字典。如果
__deepcopy__
实现需要对组件进行深层复制,则应将组件作为第一个参数,将 memo 字典作为第二个参数来调用deepcopy()
函数。memo 字典应被视为不透明对象。
函数 copy.replace()
比 copy()
和 deepcopy()
的功能更有限,仅支持由 namedtuple()
、dataclasses
和其他定义方法 __replace__()
的类创建的命名元组。
- object.__replace__(self, /, **changes)¶
此方法应创建一个相同类型的新对象,并用 changes 中的值替换字段。
另请参阅
- 模块
pickle
关于用于支持对象状态检索和恢复的特殊方法的讨论。