真正隔离嵌套结构需用copy.deepcopy();copy.copy()和dict.copy()仅为浅拷贝,仅复制顶层键值对,嵌套的可变对象仍共享引用,修改副本会影响原对象。

直接用 copy.deepcopy() 才算真正隔离嵌套结构;用 copy.copy() 或 dict.copy() 只能骗过第一层,嵌套里的列表、字典、自定义对象仍共享引用。
为什么 dict.copy() 不等于深拷贝
它只是浅拷贝的一种快捷写法,只复制字典顶层键值对,所有可变值(比如嵌套的 list、dict、set)依然共用内存地址。
- 当你改
copied_dict['users'][0]['name'],原始字典里同位置的值也会变 -
id(original_dict['config']) == id(copied_dict['config'])很可能为True - 对不可变值(如
str、int、tuple)没问题,但一碰可变类型就露馅
copy.deepcopy() 的实际行为和限制
它递归遍历所有层级,为每个可变子对象新建实例,但会跳过无法序列化的类型(如文件句柄、线程锁、函数、模块),并原样返回这些对象——不是报错,而是“不复制”。
- 遇到循环引用(比如字典里存了自己:
d['me'] = d),deepcopy()能靠内部memo字典避免无限递归 - 性能开销明显:嵌套越深、数据越庞大,耗时越长;小数据无所谓,高频调用或大数据量时得权衡
- 自定义类如果定义了
__deepcopy__()方法,会被优先调用;否则按默认逻辑处理
哪些场景下不该无脑用 deepcopy
不是所有嵌套字典都需要彻底隔离。过度深拷贝反而引入隐蔽问题。
- 配置字典里包含预编译的正则对象
re.compile(...):深拷贝后变成普通字符串或失效,应保留引用 - 缓存结构中多个字典共享同一份
defaultdict实例:深拷贝会破坏共享语义 - 对象里有数据库连接、socket、临时文件句柄:深拷贝无法复制,且强行复制可能引发资源泄漏
- 使用
dataclass或NamedTuple且含可变字段时,需确认是否真要复制其内部状态
最易被忽略的是:深拷贝不等于“安全”,它只是把引用关系切断;如果原始字典里存的是全局单例、弱引用对象或带副作用的描述符,深拷贝后行为可能和预期不一致。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











