本文目录导读:

我来用一个简单的例子来说明Python中的深拷贝和浅拷贝:
基础示例:包含可变对象的情况
import copy
# 创建一个包含列表的字典(可变对象)
original = {
'name': 'Alice',
'hobbies': ['reading', 'swimming'],
'scores': {'math': 95, 'english': 88}
}
# 1. 浅拷贝
shallow_copy = copy.copy(original)
# 2. 深拷贝
deep_copy = copy.deepcopy(original)
# 修改原始数据中的可变对象
original['hobbies'].append('coding')
original['scores']['math'] = 100
print("原始数据:", original)
print("浅拷贝结果:", shallow_copy)
print("深拷贝结果:", deep_copy)
输出结果:
原始数据: {'name': 'Alice', 'hobbies': ['reading', 'swimming', 'coding'], 'scores': {'math': 100, 'english': 88}}
浅拷贝结果: {'name': 'Alice', 'hobbies': ['reading', 'swimming', 'coding'], 'scores': {'math': 100, 'english': 88}}
深拷贝结果: {'name': 'Alice', 'hobbies': ['reading', 'swimming'], 'scores': {'math': 95, 'english': 88}}
直观理解示意图
# 原始对象
original = {
'name': 'Alice', # 不可变对象 (字符串)
'hobbies': ['reading'] # 可变对象 (列表)
}
# 浅拷贝:只拷贝第一层,内部引用共享
shallow = original # ❌ 这是赋值,不是拷贝
shallow = original.copy() # ✅ 浅拷贝:新字典,但hobbies指向同一个列表
# 深拷贝:完全独立的新对象
deep = copy.deepcopy(original) # ✅ 新字典,新列表
不同拷贝方式的对比
import copy
class Person:
def __init__(self, name, friend=None):
self.name = name
self.friend = friend
def __repr__(self):
return f"Person({self.name})"
# 创建循环引用示例
alice = Person("Alice")
bob = Person("Bob", alice)
alice.friend = bob # 循环引用
# 四种拷贝方式
print("=== 不同拷贝方式对比 ===")
# 1. 普通赋值
assignment = alice
print(f"赋值: {assignment is alice}") # True - 同一个对象
# 2. 浅拷贝
shallow = copy.copy(alice)
print(f"浅拷贝: {shallow is alice}") # False - 新对象
print(f"浅拷贝friend: {shallow.friend is alice.friend}") # True - 内部引用相同
# 3. 深拷贝
deep = copy.deepcopy(alice)
print(f"深拷贝: {deep is alice}") # False - 新对象
print(f"深拷贝friend: {deep.friend is alice.friend}") # False - 全部新对象
不可变对象的行为
# 对于只包含不可变对象的容器
immutable_data = (1, 2, 3)
string_data = "hello"
int_data = 42
# 浅拷贝和深拷贝结果相同
shallow_tuple = copy.copy(immutable_data)
deep_tuple = copy.deepcopy(immutable_data)
print(f"元组浅拷贝相同: {shallow_tuple is immutable_data}") # True
实际应用场景
# 场景1:保护原始数据
def process_data(data):
# 不想修改原始数据
data_copy = copy.deepcopy(data)
# 处理副本...
return data_copy
# 场景2:快速复制(性能考量)
def quick_duplicate(config):
# 如果config只有一层,用浅拷贝更高效
if all(isinstance(v, (str, int, float)) for v in config.values()):
return copy.copy(config) # 快速
else:
return copy.deepcopy(config) # 安全
# 场景3:拷贝自定义对象
class GameState:
def __init__(self, level, inventory):
self.level = level
self.inventory = inventory # 列表
def clone(self):
return copy.deepcopy(self)
# 使用
state = GameState(1, ["sword", "potion"])
saved_state = state.clone() # 保存存档
state.inventory.append("shield") # 不影响存档
总结要点
# 何时用浅拷贝?
# - 对象只有一层,没有嵌套可变对象
# - 不需要修改内部对象
# - 性能敏感,需要快速拷贝
# 何时用深拷贝?
# - 有嵌套可变对象
# - 需要完全独立的副本
# - 修改副本不影响原始数据
# 性能对比
import time
# 浅拷贝快
start = time.time()
for _ in range(10000):
copy.copy(original)
print(f"浅拷贝: {time.time() - start:.4f}s")
# 深拷贝慢(递归复制所有层)
start = time.time()
for _ in range(10000):
copy.deepcopy(original)
print(f"深拷贝: {time.time() - start:.4f}s")
简单记忆:
- 浅拷贝:新瓶子,旧酒(内部引用不变)
- 深拷贝:新瓶子,新酒(完全独立)