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

 更新时间:2025年11月14日 10:46:36   作者:Geoking.  
Python的copy()函数是copy模块提供的一个用于创建对象浅拷贝的工具,这篇文章主要介绍了Python中copy()函数浅拷贝与深拷贝的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

前言

在 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]

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

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

二、copy模块简介

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

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

我们先来看看浅拷贝。

三、浅拷贝 (copy.copy())

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

示例:

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]

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

四、深拷贝 (copy.deepcopy())

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

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网络编程中urllib2模块的用法总结

    Python网络编程中urllib2模块的用法总结

    使用urllib2模块进行基于url的HTTP请求等操作大家也许都比较熟悉,这里我们再深入来了解一下urllib2针对HTTP的异常处理相关功能,一起来看一下Python网络编程中urllib2模块的用法总结:
    2016-07-07
  • Python实现的多线程http压力测试代码

    Python实现的多线程http压力测试代码

    这篇文章主要介绍了Python实现的多线程http压力测试代码,结合实例形式分析了Python多线程操作的相关实现技巧,需要的朋友可以参考下
    2017-02-02
  • Python 包管理器pip入门教程

    Python 包管理器pip入门教程

    这篇文章主要为大家介绍了Python pip包管理器入门教程详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11
  • 迁移现有的python项目到pyproject.toml

    迁移现有的python项目到pyproject.toml

    本文将详细介绍将现有的 Python 项目迁移到 pyproject.toml,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-04-04
  • python设置Pyplot的动态rc参数、绘图的填充

    python设置Pyplot的动态rc参数、绘图的填充

    本文主要介绍了python设置Pyplot的动态rc参数、绘图的填充,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • Jupyter notebook如何修改平台字体

    Jupyter notebook如何修改平台字体

    这篇文章主要介绍了Jupyter notebook如何修改平台字体,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-05-05
  • Python利用selenium建立代理ip池访问网站的全过程

    Python利用selenium建立代理ip池访问网站的全过程

    selenium控制浏览器也是可以使用代理ip的,下面这篇文章主要给大家介绍了关于Python利用selenium建立代理ip池访问网站的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-03-03
  • Python编译结果之code对象与pyc文件详解

    Python编译结果之code对象与pyc文件详解

    今天小编就为大家分享一篇对Python编译结果之code对象与pyc文件的详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-10-10
  • flask上使用websocket的方法示例

    flask上使用websocket的方法示例

    本文主要介绍了flask上使用websocket的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • python数字图像处理之基本形态学滤波

    python数字图像处理之基本形态学滤波

    这篇文章主要为大家介绍了python数字图像处理之基本形态学滤波示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06

最新评论