Python案例怎么实现深度拷贝?

wen python案例 12

本文目录导读:

Python案例怎么实现深度拷贝?

  1. 基本实现
  2. 注意事项

在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

注意事项

  1. 不可变类型:字符串、数字等不可变类型在深拷贝时不会真正创建新对象
  2. 自定义对象:确保自定义类正确地实现了 __deepcopy__ 方法
  3. 性能问题:深度拷贝大型对象或复杂嵌套结构时要注意性能
  4. 内存占用:深度拷贝会创建完全独立的对象,占用更多内存
  5. 文件/网络连接:不能深度拷贝文件句柄、网络连接等系统资源

深度拷贝是Python中处理复杂对象复制的重要工具,特别是在需要完全独立的副本时非常有用。

抱歉,评论功能暂时关闭!