Python中copy() 函数浅拷贝与深拷贝示例详解

作者:

文章目录
  • 在 Python 编程中,对象的拷贝(复制) 是一个常见又容易被忽视的概念。很多初学者在使用 copy() 时,常常会遇到修改一个对象导致另一个对象也被改变的“奇怪现象”。本文将深入理解 Python 的 copy() 函数、浅拷贝与深拷贝的区别,并通过示例让你彻底搞清楚它们的原理。
  • 当你在 Python 中使用赋值语句时,例如: a = [1, 2, 3] b = a 此时,a 和 b指向同一个对象。这意味着修改 b 也会影响 a: b.append(4) print(a) # 输出:[1, 2, 3, 4] print(b) # 输出:[1, 2, 3, 4] 这往往不是我们想要的结果。 如果希望创建一个“新的对象”,而不是仅仅复制引用,这时就需要用到 拷贝函数。
  • Python 标准库提供了一个专门用于复制对象的模块:copy。该模块中有两个重要函数: copy.copy(x) —— 执行 浅拷贝 copy.deepcopy(x) —— 执行 深拷贝 我们先来看看浅拷贝。
  • 浅拷贝会创建一个新的对象,但不会递归地复制内部的可变对象。 示例: import copy list_a = [1, [2, 3], 4] list_b = copy.copy(list_a) print(list_a == list_b) # True,内容相同 print(list_a is list_b) # False,指向不同对象 修改外层列表时,互不影响: list_b.append(5) print(list_a) # [1, [2, 3], 4] print(list_b) # [1, [2, 3], 4, 5] 但修改内部的可变对象时,浅拷贝仍然会“联动”: list_b[1].append(99) print(list_a) # [1, [2, 3, 99], 4] print(list_b) # [1, [2, 3, 99], 4, 5] ✅ 结论:浅拷贝只复制最外层容器,内部元素仍然是原对象的引用。
  • 深拷贝则会递归地复制所有对象,生成完全独立的一份副本。 import copy list_a = [1, [2, 3], 4] list_b = copy.deepcopy(list_a) list_b[1].append(99) print(list_a) # [1, [2, 3], 4] print(list_b) # [1, [2, 3, 99], 4] ✅ 结论:深拷贝创建了一个完全独立的对象副本,任何修改都不会相互影响。
  • 数据类型 浅拷贝结果 深拷贝结果 int, float, str, bool 不可变对象,直接共享 相同效果 list, dict, set 复制容器,但内部引用相同 完全独立副本 tuple 如果内部包含可变对象,浅拷贝仍共享引用 内部对象独立 自定义类对象 可自定义 __copy__ / __deepcopy__ 方法 可完全控制复制逻辑
  • Python 允许开发者通过实现特殊方法 __copy__ 和 __deepcopy__ 来控制类的复制方式。 示例: import copy class Person: def __init__(self, name, hobbies): self.name = name self.hobbies = hobbies def __copy__(self): print(“调用浅拷贝”) return type(self)(self.name, self.hobbies) def __deepcopy__(self, memo): print(“调用深拷贝”) new_person = type(self)(self.name, copy.deepcopy(self.hobbies, memo)) return new_person p1 = Person(“Alice”, [“reading”, “coding”]) p2 = copy.copy(p1) p3 = copy.deepcopy(p1)
  • 浅拷贝不会递归复制内部对象 a = [[1, 2], [3, 4]] b = copy.copy(a) b[0].append(99) print(a) # [[1, 2, 99], [3, 4]] 不可变对象(如 int, str, tuple)无需担心浅拷贝问题 a = (1, 2, 3) b = copy.copy(a) print(a is b) # True 深拷贝性能开销较大深拷贝会递归复制所有内容,对于嵌套层级深或对象复杂的结构,速度会明显变慢。如果不需要完全隔离,优先使用浅拷贝。
  • 概念 是否创建新对象 是否递归复制 适用场景 赋值(=) 否 否 两变量共享同一对象 浅拷贝(copy.copy()) 是 否 仅需复制一层结构 深拷贝(copy.deepcopy()) 是 是 需要完全独立的副本
  • 若仅修改外层容器,用 copy.copy() 即可。 若修改嵌套结构(如列表中包含列表),用 copy.deepcopy()。 若对象复杂,考虑自行实现 __copy__ 与 __deepcopy__,以提升性能与控制力。 ✨ 浅拷贝复制外壳,深拷贝复制灵魂。 到此这篇关于Python中copy() 函数浅拷贝与深拷贝的文章就介绍到这了,更多相关Python中copy()函数浅拷贝深拷贝内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客! 您可能感兴趣的文章: python利用os模块编写文件复制功能——copy()函数用法 Python的对象传递与Copy函数使用详解 Python中的copy()函数详解(list,array) python copy模块中的函数实例用法
  • 目录
    • 前言
    • 一、为什么需要拷贝对象?
    • 二、copy模块简介
    • 三、浅拷贝 (copy.copy())
    • 四、深拷贝 (copy.deepcopy())
    • 五、不同数据类型的拷贝行为
    • 六、自定义类的拷贝行为
    • 七、常见坑点总结
    • 八、总结
    • 九、实践建议

    在 Python 编程中,对象的拷贝(复制) 是一个常见又容易被忽视的概念。很多初学者在使用 copy() 时,常常会遇到修改一个对象导致另一个对象也被改变的“奇怪现象”。本文将深入理解 Python 的 copy() 函数、浅拷贝与深拷贝的区别,并通过示例让你彻底搞清楚它们的原理。

    当你在 Python 中使用赋值语句时,例如:

    a = [1, 2, 3]
    b = a
    

    此时,ab指向同一个对象。这意味着修改 b 也会影响 a

    b.append(4)
    print(a)  # 输出:[1, 2, 3, 4]
    print(b)  # 输出:[1, 2, 3, 4]
    

    这往往不是我们想要的结果。

    如果希望创建一个“新的对象”,而不是仅仅复制引用,这时就需要用到 拷贝函数

    Python 标准库提供了一个专门用于复制对象的模块:copy
    该模块中有两个重要函数:

    • copy.copy(x) —— 执行 浅拷贝
    • copy.deepcopy(x) —— 执行 深拷贝

    我们先来看看浅拷贝。

    浅拷贝会创建一个新的对象,但不会递归地复制内部的可变对象

    示例:

    import copy
    
    list_a = [1, [2, 3], 4]
    list_b = copy.copy(list_a)
    
    print(list_a == list_b)  # True,内容相同
    print(list_a is list_b)  # False,指向不同对象
    

    修改外层列表时,互不影响:

    list_b.append(5)
    print(list_a)  # [1, [2, 3], 4]
    print(list_b)  # [1, [2, 3], 4, 5]
    

    但修改内部的可变对象时,浅拷贝仍然会“联动”:

    list_b[1].append(99)
    print(list_a)  # [1, [2, 3, 99], 4]
    print(list_b)  # [1, [2, 3, 99], 4, 5]
    

    ✅ 结论:浅拷贝只复制最外层容器,内部元素仍然是原对象的引用。

    深拷贝则会递归地复制所有对象,生成完全独立的一份副本。

    import copy
    
    list_a = [1, [2, 3], 4]
    list_b = copy.deepcopy(list_a)
    
    list_b[1].append(99)
    
    print(list_a)  # [1, [2, 3], 4]
    print(list_b)  # [1, [2, 3, 99], 4]
    

    ✅ 结论:深拷贝创建了一个完全独立的对象副本,任何修改都不会相互影响。

    数据类型 浅拷贝结果 深拷贝结果
    int, float, str, bool 不可变对象,直接共享 相同效果
    list, dict, set 复制容器,但内部引用相同 完全独立副本
    tuple 如果内部包含可变对象,浅拷贝仍共享引用 内部对象独立
    自定义类对象 可自定义 __copy__ / __deepcopy__ 方法 可完全控制复制逻辑

    Python 允许开发者通过实现特殊方法 __copy____deepcopy__ 来控制类的复制方式。

    示例:

    import copy
    
    class Person:
        def __init__(self, name, hobbies):
            self.name = name
            self.hobbies = hobbies
    
        def __copy__(self):
            print("调用浅拷贝")
            return type(self)(self.name, self.hobbies)
    
        def __deepcopy__(self, memo):
            print("调用深拷贝")
            new_person = type(self)(self.name, copy.deepcopy(self.hobbies, memo))
            return new_person
    
    p1 = Person("Alice", ["reading", "coding"])
    p2 = copy.copy(p1)
    p3 = copy.deepcopy(p1)
    

    1. 浅拷贝不会递归复制内部对象
    a = [[1, 2], [3, 4]]
    b = copy.copy(a)
    b[0].append(99)
    print(a)  # [[1, 2, 99], [3, 4]]
    
    1. 不可变对象(如 int, str, tuple)无需担心浅拷贝问题
    a = (1, 2, 3)
    b = copy.copy(a)
    print(a is b)  # True
    
    1. 深拷贝性能开销较大
      深拷贝会递归复制所有内容,对于嵌套层级深或对象复杂的结构,速度会明显变慢。
      如果不需要完全隔离,优先使用浅拷贝。

    概念 是否创建新对象 是否递归复制 适用场景
    赋值(= 两变量共享同一对象
    浅拷贝(copy.copy() 仅需复制一层结构
    深拷贝(copy.deepcopy() 需要完全独立的副本

    • 若仅修改外层容器,用 copy.copy() 即可。
    • 若修改嵌套结构(如列表中包含列表),用 copy.deepcopy()
    • 若对象复杂,考虑自行实现 __copy____deepcopy__,以提升性能与控制力。

    浅拷贝复制外壳,深拷贝复制灵魂。

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

    您可能感兴趣的文章:

    • python利用os模块编写文件复制功能——copy()函数用法
    • Python的对象传递与Copy函数使用详解
    • Python中的copy()函数详解(list,array)
    • python copy模块中的函数实例用法

    站内搜索