一文详细了解python的深浅拷贝

Written by

in

文章目录
  • 深拷贝(Deep Copy)是Python中一种递归复制对象的方式,它会创建一个新对象,并递归地复制原对象内部的所有子对象。这意味着深拷贝后的对象与原对象完全独立,修改其中一个不会影响另一个。深拷贝适用于需要完全独立副本的场景,尤其是当对象内部包含嵌套的可变对象时。
  • 深浅拷贝在实际编程中有广泛的应用,尤其是在处理复杂数据结构或需要确保数据独立性时。以下是一些常见的应用场景和示例,帮助你更好地理解它们的实际用途。 
  • 到此这篇关于python深浅拷贝的文章就介绍到这了,更多相关python深浅拷贝内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客! 您可能感兴趣的文章: Python 拷贝对象(深拷贝deepcopy与浅拷贝copy) Python中的深拷贝和浅拷贝详解 Python对象的深拷贝和浅拷贝详解 Python中深拷贝与浅拷贝的区别介绍 详解Python中深浅拷贝的使用及注意事项 Python 的赋值,浅拷贝和深拷贝详解 深入理解python中的浅拷贝和深拷贝 Python列表的浅拷贝与深拷贝
  • 目录
    • 浅拷贝:
      • 1.浅拷贝的定义:
      • 2.浅拷贝的实现方式
        • (1)使用copy模块的copy()函数
        • (2)使用列表、字典等数据结构的工厂函数
        • (3)使用切片操作(适用于列表)
        • (4)使用字典的copy()方法
      •  3.浅拷贝的特点
        • 4.浅拷贝的示例
          • 示例 1:修改浅拷贝后的对象
          • 示例 2:使用切片操作实现浅拷贝
          • 示例 3:字典的浅拷贝
        • 5.浅拷贝的适用场景
          • 6.浅拷贝的注意事项
          • 深拷贝:
            • 1.深拷贝的定义
              • 2.深拷贝的实现方式
                • 3.深拷贝的特点
                  • 4.深拷贝的示例
                    • 示例 1:修改深拷贝后的对象
                    • 示例 2:嵌套字典的深拷贝
                    • 示例 3:自定义对象的深拷贝
                  • 5.深拷贝的适用场景
                    • 6.深拷贝的注意事项
                      • 7.深拷贝的实现原理
                      • 深浅拷贝的实际应用:
                        • 1.数据处理与修改
                          • 2.配置管理
                            • 3.对象复制与状态管理
                              • 4. 避免副作用
                              • 总结

                                深浅拷贝是什么:在Python中,理解深拷贝(deep copy)和浅拷贝(shallow copy)对于处理复杂的数据结构,如列表、字典或自定义对象,是非常重要的。这两种拷贝方式决定了数据在内存中的复制方式,进而影响程序的运行结果

                                浅拷贝是一种复制操作,它创建一个新对象,并将原对象的内容复制到新对象中。对于原对象内部的子对象,浅拷贝不会递归地复制它们,而是直接引用这些子对象。因此,浅拷贝后的对象和原对象共享内部的子对象。

                                import copy
                                
                                original_list = [1, 2, [3, 4]]
                                shallow_copied_list = copy.copy(original_list)

                                original_list = [1, 2, [3, 4]]
                                shallow_copied_list = list(original_list)  # 列表的工厂函数

                                original_list = [1, 2, [3, 4]]
                                shallow_copied_list = original_list[:]  # 切片操作

                                original_dict = {'a': 1, 'b': [2, 3]}
                                shallow_copied_dict = original_dict.copy()  # 字典的 copy() 方法

                                • 新对象,旧引用:浅拷贝会创建一个新对象,但对象内部的子对象仍然是原对象中子对象的引用。

                                • 共享子对象:如果原对象包含可变子对象(如列表、字典等),修改这些子对象会影响浅拷贝后的对象。

                                性能较高:由于浅拷贝不会递归复制子对象,因此它的性能比深拷贝更高。

                                import copy
                                
                                original_list = [1, 2, [3, 4]]
                                shallow_copied_list = copy.copy(original_list)
                                
                                # 修改浅拷贝后的对象
                                shallow_copied_list[0] = 100
                                shallow_copied_list[2][0] = 300
                                
                                print("Original List:", original_list)
                                print("Shallow Copied List:", shallow_copied_list)

                                输出

                                Original List: [1, 2, [300, 4]]
                                Shallow Copied List: [100, 2, [300, 4]]

                                解释:

                                • 修改 shallow_copied_list[0] 不会影响 original_list,因为这是对新对象本身的修改。

                                • 修改 shallow_copied_list[2][0] 会影响 original_list,因为内部的子列表是共享的。

                                original_list = [1, 2, [3, 4]]
                                shallow_copied_list = original_list[:]
                                
                                # 修改浅拷贝后的对象
                                shallow_copied_list[0] = 100
                                shallow_copied_list[2][0] = 300
                                
                                print("Original List:", original_list)
                                print("Shallow Copied List:", shallow_copied_list)

                                输出

                                Original List: [1, 2, [300, 4]]
                                Shallow Copied List: [100, 2, [300, 4]]

                                original_dict = {'a': 1, 'b': [2, 3]}
                                shallow_copied_dict = original_dict.copy()
                                
                                # 修改浅拷贝后的字典
                                shallow_copied_dict['a'] = 100
                                shallow_copied_dict['b'][0] = 200
                                
                                print("Original Dict:", original_dict)
                                print("Shallow Copied Dict:", shallow_copied_dict)

                                输出

                                Original Dict: {'a': 1, 'b': [200, 3]}
                                Shallow Copied Dict: {'a': 100, 'b': [200, 3]}

                                解释:

                                • 修改 shallow_copied_dict['a'] 不会影响 original_dict,因为这是对新对象本身的修改。

                                • 修改 shallow_copied_dict['b'][0] 会影响 original_dict,因为内部的列表是共享的。

                                浅拷贝适用于以下场景:

                                • 对象内部没有嵌套的可变对象:如果对象内部只包含不可变对象(如整数、字符串、元组等),浅拷贝是安全的。

                                • 性能要求较高:浅拷贝的性能比深拷贝更高,因为它不会递归复制子对象。

                                • 共享子对象是期望的行为:如果你希望拷贝后的对象和原对象共享某些子对象,浅拷贝是一个合适的选择。

                                共享子对象的风险:如果原对象包含可变子对象,修改这些子对象会影响浅拷贝后的对象。如果不希望共享子对象,应该使用深拷贝。

                                不可变对象的特殊性:对于不可变对象(如整数、字符串、元组等),浅拷贝和深拷贝的行为是相同的,因为不可变对象不能被修改。

                                深拷贝(Deep Copy)是Python中一种递归复制对象的方式,它会创建一个新对象,并递归地复制原对象内部的所有子对象。这意味着深拷贝后的对象与原对象完全独立,修改其中一个不会影响另一个。深拷贝适用于需要完全独立副本的场景,尤其是当对象内部包含嵌套的可变对象时。

                                深拷贝是一种递归复制操作,它创建一个新对象,并递归地复制原对象内部的所有子对象。深拷贝后的对象与原对象完全独立,即使原对象包含嵌套的可变对象(如列表、字典等),修改其中一个对象也不会影响另一个。

                                在Python中,可以通过 copy 模块的 deepcopy() 函数实现深拷贝。

                                使用copy.deepcopy()函数

                                • 完全独立:深拷贝后的对象与原对象完全独立,修改其中一个不会影响另一个。

                                • 递归复制:深拷贝会递归地复制对象内部的所有子对象,包括嵌套的可变对象。

                                • 性能较低:由于深拷贝需要递归复制所有子对象,因此它的性能比浅拷贝低,尤其是在处理大型或复杂的嵌套结构时。

                                通过以下示例,可以更好地理解深拷贝的行为。

                                输出: 

                                Original List: [1, 2, [3, 4]]
                                Deep Copied List: [100, 2, [300, 4]]

                                解释:

                                • 修改 deep_copied_list[0] 不会影响 original_list,因为这是对新对象本身的修改。

                                • 修改 deep_copied_list[2][0] 也不会影响 original_list,因为深拷贝递归复制了内部的子列表,两个列表是完全独立的。

                                输出: 

                                Original Dict: {'name': 'Alice', 'details': {'age': 25, 'hobbies': ['reading', 'traveling']}}
                                Deep Copied Dict: {'name': 'Alice', 'details': {'age': 30, 'hobbies': ['reading', 'traveling', 'cooking']}}

                                解释:

                                • 修改 deep_copied_dict 中的嵌套字典和列表不会影响 original_dict,因为深拷贝递归复制了所有子对象。

                                输出

                                解释:

                                修改 person2 的 name 和 friends 不会影响 person1,因为深拷贝递归复制了所有属性。

                                深拷贝适用于以下场景:

                                • 需要完全独立的副本:当对象内部包含嵌套的可变对象时,深拷贝可以确保副本与原对象完全独立。

                                • 复杂的数据结构:如嵌套的列表、字典、自定义对象等。

                                • 避免副作用:在函数中传递复杂对象时,深拷贝可以避免意外修改原对象。

                                • 性能开销:深拷贝需要递归复制所有子对象,因此在处理大型或复杂的嵌套结构时,性能开销较大。

                                • 循环引用问题:如果对象之间存在循环引用(如对象A引用对象B,对象B又引用对象A),深拷贝可能会导致栈溢出或无限递归。Python的 copy.deepcopy() 函数已经处理了循环引用问题,但在自定义深拷贝逻辑时需要注意。

                                Python的 copy.deepcopy() 函数通过递归遍历对象的所有属性来实现深拷贝。它会维护一个备忘录(memo)来记录已经复制的对象,从而避免循环引用导致的无限递归。

                                深浅拷贝在实际编程中有广泛的应用,尤其是在处理复杂数据结构或需要确保数据独立性时。以下是一些常见的应用场景和示例,帮助你更好地理解它们的实际用途。 

                                在处理数据时,尤其是嵌套的数据结构(如列表嵌套列表、字典嵌套字典等),你可能需要在不影响原始数据的情况下对数据进行修改或分析。这时,深拷贝非常有用。 

                                import copy
                                
                                # 原始数据
                                original_data = {
                                    'name': 'Alice',
                                    'scores': [90, 85, 88],
                                    'details': {'age': 25, 'city': 'New York'}
                                }
                                
                                # 深拷贝数据
                                copied_data = copy.deepcopy(original_data)
                                
                                # 修改拷贝后的数据
                                copied_data['scores'][0] = 95
                                copied_data['details']['city'] = 'San Francisco'
                                
                                # 原始数据不受影响
                                print("Original Data:", original_data)
                                print("Copied Data:", copied_data)

                                应用场景:

                                • 数据备份与恢复。

                                • 数据预处理(如修改数据后用于机器学习模型训练,而不影响原始数据)。

                                在程序中,配置通常以字典或嵌套字典的形式存储。如果你需要基于某个默认配置生成多个独立的配置,深拷贝可以确保每个配置之间互不干扰。 

                                import copy
                                
                                # 默认配置
                                default_config = {
                                    'debug': False,
                                    'database': {
                                        'host': 'localhost',
                                        'port': 3306
                                    }
                                }
                                
                                # 创建多个独立配置
                                config_1 = copy.deepcopy(default_config)
                                config_2 = copy.deepcopy(default_config)
                                
                                # 修改配置
                                config_1['database']['host'] = '192.168.1.1'
                                config_2['debug'] = True
                                
                                print("Config 1:", config_1)
                                print("Config 2:", config_2)

                                应用场景:

                                • 多环境配置(开发、测试、生产)。

                                • 动态生成多个独立的配置。

                                在面向对象编程中,对象可能包含嵌套的对象或复杂的状态。如果你需要复制一个对象并确保新对象的状态独立于原对象,深拷贝是必要的。 

                                import copy
                                
                                class Player:
                                    def __init__(self, name, level):
                                        self.name = name
                                        self.level = level
                                        self.inventory = []
                                
                                    def add_item(self, item):
                                        self.inventory.append(item)
                                
                                # 创建玩家对象
                                player1 = Player("Alice", 10)
                                player1.add_item("Sword")
                                player1.add_item("Shield")
                                
                                # 深拷贝玩家对象
                                player2 = copy.deepcopy(player1)
                                
                                # 修改拷贝后的对象
                                player2.name = "Bob"
                                player2.add_item("Bow")
                                
                                # 查看两个对象的状态
                                print(f"Player 1: {player1.name}, {player1.inventory}")
                                print(f"Player 2: {player2.name}, {player2.inventory}")

                                应用场景:

                                • 游戏开发中复制角色或物品。

                                • 状态快照与恢复(如撤销操作)。

                                def process_data(data):
                                    # 浅拷贝数据以避免修改原始数据
                                    data_copy = data.copy()
                                    data_copy.append("Processed")
                                    return data_copy
                                
                                original_data = [1, 2, 3]
                                result = process_data(original_data)
                                
                                print("Original Data:", original_data)
                                print("Result:", result)

                                应用场景:

                                • 函数式编程中避免副作用。

                                • 数据处理管道中确保数据独立性。

                                • 深拷贝:适用于需要完全独立副本的场景,如数据处理、配置管理、对象复制等。

                                • 浅拷贝:适用于性能敏感的场景,或者当对象内部没有嵌套结构时。

                                建议 选择使用深拷贝还是浅拷贝取决于具体的需求和数据结构。如果你不确定,深拷贝通常是更安全的选择,尽管它可能会带来一些性能开销。

                                到此这篇关于python深浅拷贝的文章就介绍到这了,更多相关python深浅拷贝内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客!

                                您可能感兴趣的文章:

                                • Python 拷贝对象(深拷贝deepcopy与浅拷贝copy)
                                • Python中的深拷贝和浅拷贝详解
                                • Python对象的深拷贝和浅拷贝详解
                                • Python中深拷贝与浅拷贝的区别介绍
                                • 详解Python中深浅拷贝的使用及注意事项
                                • Python 的赋值,浅拷贝和深拷贝详解
                                • 深入理解python中的浅拷贝和深拷贝
                                • Python列表的浅拷贝与深拷贝

                                站内搜索