本文目录导读:

在Python中,深度拷贝(deep copy)可以通过 copy 模块的 deepcopy() 函数来实现,深度拷贝会创建一个全新的对象,并递归地复制所有嵌套的对象,使得原对象和拷贝对象完全独立。
基本实现
使用 copy.deepcopy()
import copy
# 示例对象
original = {
'name': 'Alice',
'hobbies': ['reading', 'swimming'],
'address': {
'city': 'Beijing',
'zip': '100000'
}
}
# 深度拷贝
copied = copy.deepcopy(original)
# 修改拷贝对象
copied['hobbies'].append('coding')
copied['address']['city'] = 'Shanghai'
print("Original:", original)
print("Copied:", copied)
自定义深度拷贝实现
如果你想理解深度拷贝的原理,可以自己实现一个简单的版本:
def deep_copy(obj):
"""自定义深度拷贝函数"""
# 处理基本类型(不可变类型)
if obj is None:
return None
if isinstance(obj, (int, float, bool, str, bytes)):
return obj
# 处理列表
if isinstance(obj, list):
return [deep_copy(item) for item in obj]
# 处理字典
if isinstance(obj, dict):
return {key: deep_copy(value) for key, value in obj.items()}
# 处理元组
if isinstance(obj, tuple):
return tuple(deep_copy(item) for item in obj)
# 处理集合
if isinstance(obj, set):
return {deep_copy(item) for item in obj}
# 处理其他对象
try:
# 尝试创建新的对象实例
new_obj = obj.__class__.__new__(obj.__class__)
if hasattr(obj, '__dict__'):
for key, value in obj.__dict__.items():
setattr(new_obj, key, deep_copy(value))
return new_obj
except Exception as e:
# 如果无法处理,返回原对象
print(f"Warning: Could not deep copy {type(obj)}: {e}")
return obj
# 测试自定义深度拷贝
class Person:
def __init__(self, name, age, hobbies):
self.name = name
self.age = age
self.hobbies = hobbies
def __repr__(self):
return f"Person(name='{self.name}', age={self.age}, hobbies={self.hobbies})"
# 创建测试对象
original_person = Person("Bob", 30, ["reading", "swimming"])
copied_person = deep_copy(original_person)
# 修改拷贝对象
copied_person.hobbies.append("coding")
print("Original:", original_person)
print("Copied:", copied_person)
实际应用案例
import copy
class ShoppingCart:
"""购物车示例"""
def __init__(self):
self.items = []
self.discounts = []
def add_item(self, item, price, quantity=1):
self.items.append({
'item': item,
'price': price,
'quantity': quantity
})
def add_discount(self, code, percentage):
self.discounts.append({
'code': code,
'percentage': percentage
})
def __repr__(self):
return f"Items: {self.items}\nDiscounts: {self.discounts}"
# 创建原始购物车
cart1 = ShoppingCart()
cart1.add_item("Apple", 5.0, 3)
cart1.add_item("Banana", 3.0, 2)
cart1.add_discount("SUMMER20", 20)
# 深度拷贝购物车
cart2 = copy.deepcopy(cart1)
# 修改 cart2
cart2.add_item("Orange", 4.0, 1)
cart2.add_discount("WINTER10", 10)
cart2.items[0]['quantity'] = 5
print("Cart 1 (Original):")
print(cart1)
print("\nCart 2 (Copied and modified):")
print(cart2)
# 验证完全独立
print("\nAre cart1 and cart2 independent?")
print(f"cart1 is cart2: {cart1 is cart2}") # False
print(f"cart1.items is cart2.items: {cart1.items is cart2.items}") # False
处理循环引用
深度拷贝还能正确处理循环引用的情况:
import copy
class Node:
def __init__(self, value):
self.value = value
self.next = None
self.prev = None
def __repr__(self):
return f"Node({self.value})"
# 创建循环链表
node1 = Node(1)
node2 = Node(2)
node3 = Node(3)
node1.next = node2
node2.prev = node1
node2.next = node3
node3.prev = node2
node3.next = node1 # 形成循环引用
node1.prev = node3
# 深度拷贝循环引用的对象
copied_node1 = copy.deepcopy(node1)
print("Original node1:", id(node1))
print("Copied node1:", id(copied_node1))
print("Are they the same object?", node1 is copied_node1) # False
print("Original circular reference preserved:", copied_node1.next.next.next.value) # 1
性能考虑
对于大数据量,深度拷贝可能比较耗时:
import copy
import time
# 创建一个包含大量数据的列表
big_data = [[i for i in range(1000)] for _ in range(1000)]
# 比较浅拷贝和深拷贝的性能
start = time.time()
shallow = copy.copy(big_data)
shallow_time = time.time() - start
start = time.time()
deep = copy.deepcopy(big_data)
deep_time = time.time() - start
print(f"Shallow copy time: {shallow_time:.4f} seconds")
print(f"Deep copy time: {deep_time:.4f} seconds")
# 修改测试
shallow[0][0] = -1
print(f"Modifying shallow copy affects original: {big_data[0][0] == -1}") # True
deep[0][0] = -2
print(f"Modifying deep copy affects original: {big_data[0][0] == -2}") # False
注意事项
- 不可变类型:字符串、数字等不可变类型在深拷贝时不会真正创建新对象
- 自定义对象:确保自定义类正确地实现了
__deepcopy__方法 - 性能问题:深度拷贝大型对象或复杂嵌套结构时要注意性能
- 内存占用:深度拷贝会创建完全独立的对象,占用更多内存
- 文件/网络连接:不能深度拷贝文件句柄、网络连接等系统资源
深度拷贝是Python中处理复杂对象复制的重要工具,特别是在需要完全独立的副本时非常有用。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播