copy.deepcopy() 天然支持列表、字典、元组、集合、frozenset、deque、int、float、str、bool、none、bytes、bytearray及嵌套组合和用户定义类;遇不可序列化类型需自定义__deepcopy__方法,特殊对象如函数、numpy数组等应选用专用方案。

直接用 copy.deepcopy() 就是通用深拷贝工具的最简实现——它原生支持列表、字典、元组、集合、自定义类(默认情况下)、嵌套结构,甚至能自动处理循环引用。
哪些类型天然被支持
Python 的 copy.deepcopy() 已覆盖绝大多数内置可序列化类型:
- 容器类:list、dict、tuple、set、frozenset、deque
- 数值与不可变类型:int、float、str、bool、None、bytes、bytearray(注意:bytearray 是可变的,但 deepcopy 能安全处理)
- 嵌套组合:如
[{'a': [1, {'b': 2}]}, (3, 4)]这类混合结构 - 用户定义类:只要不包含不可序列化资源(如文件句柄、锁、socket),默认即可深拷贝
遇到不支持类型时怎么扩展
当对象含不可序列化字段(如 _thread.RLock、open('file.txt')、C 扩展对象)时,deepcopy 会报错。此时需在类中定义 __deepcopy__ 方法手动控制:
- 跳过不该拷贝的字段(如日志器、连接池、锁):
new_obj.logger = self.logger - 对需深拷的字段显式调用:
new_obj.data = copy.deepcopy(self.data, memo) - 务必传入
memo参数,避免循环引用死循环 - 若某字段应重建(如打开新文件),就在
__deepcopy__中 new 一个
需要额外兼容的边界情况
某些特殊对象需预处理或封装才能安全深拷贝:
-
函数/lambda:默认不可拷贝,可用
cloudpickle替代copy模块(适用于序列化到远程或保存) -
NumPy 数组:
deepcopy可用,但效率低;推荐用.copy()方法(更轻量且语义明确) -
dataclass 或 Pydantic 模型:通常自带
.model_copy()或replace(),比通用 deepcopy 更精准高效 -
带 __slots__ 的类:只要没禁用
__dict__或自定义了__getstate__,deepcopy 仍可工作
封装一个带容错的通用工具函数
可以封装一层,捕获常见异常并给出提示,而不是让程序崩在 TypeError 上:
- 先尝试
copy.deepcopy(obj) - 若失败且错误含
"cannot pickle",说明含不可序列化资源,建议用户重写__deepcopy__ - 若失败且是循环引用深度超限(极少见),可调大
sys.setrecursionlimit()(谨慎使用) - 对已知类型(如
np.ndarray)走专用路径,兼顾性能与正确性











