deepcopy 递归复制嵌套结构但遇不可序列化对象(如线程锁、未实现 __deepcopy__ 的自定义类)会报错;性能差、慎用于热路径;循环引用可致 recursionerror。

deepcopy 会递归复制嵌套结构,但对不可复制对象会报错
deepcopy 不是简单地复制顶层键值,而是逐层进入每个可变对象(如 dict、list、set)并新建副本。遇到函数、模块、线程锁、文件句柄等不可序列化对象时,会抛出 TypeError: cannot pickle ... 或 AttributeError。
- 常见错误现象:
TypeError: cannot pickle _thread.RLock objects—— 字典里不小心存了线程锁或类实例 - 使用场景:配置字典含多层
dict和list,需修改副本不影响原始数据 - 参数差异:
deepcopy(obj, memo=None)中memo是内部缓存字典,一般不用传;手动传memo主要用于自定义拷贝逻辑或避免循环引用死循环
嵌套字典中含自定义类实例时 deepcopy 可能失败
如果嵌套字典的某个值是未实现 __reduce__ 或 __getstate__ 的自定义类实例,deepcopy 会尝试 pickle 它,失败后直接中断。
Python 3.14.2是Python编程语言在2025年12月5日发布的稳定版本,属于3.14系列的第二个维护更新。该版本包含了18项修复,重点解决了多进程、数据类及正则表达式等模块的回归问题,并修复了CVE-2025-12084等安全漏洞。此版本标志着自由线程模式(移除GIL)正式获得官方支持,是Python发展的重要里程碑。
- 验证方式:先用
import pickle; pickle.dumps(obj)测试能否序列化 - 解决路径:给类加
__copy__和__deepcopy__方法,例如在__deepcopy__中返回MyClass(**self.__dict__.copy()) - 性能影响:每层递归调用构造函数和属性赋值,比纯内置类型慢 3–5 倍;含大量小字典时,开销明显
deepcopy 比浅拷贝慢得多,别在热路径滥用
对含 10 层嵌套、总键值对超 1000 的字典,deepcopy 耗时可能是 copy.copy 的 20 倍以上,且内存占用翻倍。
- 替代方案:若只读或仅改最外层,用
dict(original_dict)或{**original_dict}即可 - 若只改某一层子字典,可手动重建:
new = {k: v.copy() if isinstance(v, dict) else v for k, v in original.items()} - 兼容性注意:Python 3.7+ 的
dict保证插入顺序,deepcopy保留顺序;3.6 及更早版本不保证,但实际行为通常一致
循环引用会导致 deepcopy 无限递归或爆栈
当嵌套字典里存在自引用(比如 d['a'] = d)或跨层级闭环(d1['ref'] = d2,d2['back'] = d1),deepcopy 默认能检测并终止,但会消耗额外内存记录已访问对象。
- 错误信息示例:
RecursionError: maximum recursion depth exceeded—— 说明memo缓存失效或对象结构异常复杂 - 安全做法:提前检查循环引用,可用
id()遍历追踪,或用第三方库如objgraph - 容易被忽略的点:某些 ORM 模型对象(如 SQLAlchemy 的
InstanceState)内部自带循环引用,直接deepcopy几乎必崩
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










