有些 Bug,不是代码写错了,而是你以为自己复制了一个对象。
今天我们聊一个 Python 中非常常见、但极易误用的知识点:👉 浅拷贝(Shallow Copy) vs 深拷贝(Deep Copy)
一个“看起来没问题”的需求
假设我们有一个学生信息结构:
student_a = { "name": "Alice", "scores": [90, 95, 88]}
现在我们想做一份备份:
然后修改 student_b:
student_b["scores"].append(100)
你可能以为:
print(student_a)print(student_b)
输出:
{'name': 'Alice', 'scores': [90, 95, 88, 100]}{'name': 'Alice', 'scores': [90, 95, 88, 100]}
😱 两个对象一起变了!
问题根源:Python 中的“赋值 ≠ 拷贝”
这行代码并没有创建新对象,只是:
浅拷贝:copy() 到底拷贝了什么?
1️⃣ 使用 copy()
student_b = student_a.copy()student_b["scores"].append(100)
结果:
print(student_a)print(student_b)# 输出结果:{'name': 'Alice', 'scores': [90, 95, 88, 100]}{'name': 'Alice', 'scores': [90, 95, 88, 100]}
2️⃣ 浅拷贝的本质
浅拷贝只复制“第一层结构”,内部的可变对象仍然是“共享的”。
dict(新) ──▶ scores list(旧)dict(旧) ──▶ scores list(旧)
深拷贝:真正的“完全复制”
要解决这个问题,需要使用 深拷贝。1️⃣ 正确写法
import copystudent_b = copy.deepcopy(student_a)student_b["scores"].append(100)
再看结果:
print(student_a)print(student_b)# 输出{'name': 'Alice', 'scores': [90, 95, 88]}{'name': 'Alice', 'scores': [90, 95, 88, 100]}
✅ 这次才是真正的复制
什么时候必须用深拷贝?
✅ 必须用 deepcopy 的场景
一个“实战级”示例(很常见)
history = []def save_state(state): history.append(state.copy())state = {"step": 1, "nodes": [1, 2, 3]}save_state(state)state["nodes"].append(4)save_state(state)print(history)
你以为历史状态是:
[{'step': 1, 'nodes': [1, 2, 3]}, {'step': 1, 'nodes': [1, 2, 3, 4]}]
实际是:
[{'step': 1, 'nodes': [1, 2, 3, 4]}, {'step': 1, 'nodes': [1, 2, 3, 4]}]
👉 正确做法:
history.append(copy.deepcopy(state))
总结
在 Python 中:复制结构,不等于复制数据。一旦遇到嵌套可变对象,要么你非常确定,要么请用 deepcopy。
往期文章: