首页 > 编程语言 >python中copy模块的使用,深拷贝和浅拷贝

python中copy模块的使用,深拷贝和浅拷贝

时间:2024-11-12 13:46:39浏览次数:3  
标签:python 对象 复制 模块 deepcopy 拷贝 copy id

文章目录

python的轮子太多啦,下面介绍一下这个小模块的使用


一、copy模块的介绍

1、copy模块

copy模块用于对象的拷贝操作。copy模块非常简单,只有两个api。分别是copy.copy(x)和copy.deepcopy(x)。这两个函数分别返回参数x的浅复制和深复制。该模块只提供了两个主要的方法:

  • copy.copy:浅复制(Shallow copy)
  • copy.deepcopy:深复制(Deep copy)

二、copy模块的使用

  • copy仅拷贝对象本身,而不对其中的子对象进行拷贝,故对子对象进行修改也会随着修改。(例如下面的:[1,2,3, [2,3],4] 其中[2,3] 就是子对象)
  • deepcopy是真正意义上的复制,即从新开辟一片空间。我们经常说的复制实际上就是deepcopy.(深拷贝之后的对象是不受原对象的影响,无论原对象发生什么修改,深拷贝的对象都不会发生改变
>>> import copy
>>> a = [1,2,3, [2,3],4]
>>> b = a
>>> c = copy.copy(a)
>>> c
[1, 2, 3, [2, 3], 4]
>>>
>>> b
[1, 2, 3, [2, 3], 4]
>>> d = copy.deepcopy(a)
>>> d
[1, 2, 3, [2, 3], 4]
>>> a[3][0]=222
>>> a
[1, 2, 3, [222, 3], 4]
>>> b
[1, 2, 3, [222, 3], 4]
>>> c
[1, 2, 3, [222, 3], 4]
>>> d
[1, 2, 3, [2, 3], 4]
  1. 复制引用

在Python里,一切皆对象。当用赋值运算符将某个对象x赋值给另外一个对象y时,仅仅只是将x的引用赋值给y。本质上x和y指向的是同一块内存区域。这里可以使用Python的内建函数id()进行验证:

x = [1, 2, 3]
y = x
print(id(x) == id(y)) # True
  1. 克隆对象

如果想要对目标进行克隆,而不是简单的引用绑定,就需要用到copy模块。使用copy模块可以创建一个与原对象一模一样的新对象。

import copy
x = [1, 2, 3]
y = copy.copy(x)
print(id(x) == id(y)) # False
  1. 克隆策略

当对象x里面包含了另外一个对象z,甚至对象z里面包含了对象a、对象b、对象c。情况就变得复杂了。这个时候有两种策略可以选择:

  • 仅仅创建一个新对象y,而y里面的对象z,通过复制引用绑定到同一个对象上。
  • 递归地克隆目标对象及目标对象中包含的其他对象。

这两种策略,就对应了copy模块里面的copy()和deepcopy()。

使用浅复制策略时:

import copy
x = [[1, 2, 3]]
y = copy.copy(x)
print(id(x) == id(y)) # False
print(id(x[0]) == id(y[0])) # True    浅拷贝,并没有改变子对象的

使用深复制策略时:

import copy
x = [[1, 2, 3]]
y = copy.deepcopy(x)
print(id(x) == id(y)) # False
print(id(x[0]) == id(y[0])) # False

简单的说就是有没有递归调用的区别。

可以看出,深复制更加彻底,可以由里到外创建一个完完全全的新对象而不受原对象影响。但这也会导致一些问题的出现:

  • 对于某些过于复杂的对象,深复制可能会严重拖累程序的运行。
  • 某些共享数据并不需要复制,深复制会导致不同对象之间不同步。

当然,deepcopy()函数也使用了一些方法避免以上情况的出现:

  • 维护一个“memo”字典,保存当前复制操作已经复制过的对象。
  • 允许用户自定义克隆策略。

至于选择哪种克隆策略,还是要具体问题具体分析。

  1. 自定义克隆策略

用户自定义的类允许重写copy和deepcopy函数,这样就可以自定义调用copy模块时的操作,自行调整克隆策略:

import copy

class a():
    # 重写copy函数无法额外参数
    def __copy__(self):
        return "override copy"

    # 重写deepcopy函数需要一个额外参数,字典类型
    def __deepcopy__(self, memo):
        return "override deepcopy"

x = a()
print(copy.copy(x)) # override copy
print(copy.deepcopy(x)) # override deepcopy
  1. 其他需要注意的地方
  • copy模块无法复制诸如:type、函数、stack trace、stack frame、file、socket、window、array等类型。调用copy模块复制上述类型的对象会返回原对象或者直接报错。

  • 字典的浅复制可以使用y = x.copy()。而列表可以通过使用切片达到同样的目的y = x[:]

拓展说明:

1、id( )函数的使用

python中会为每个对象分配内存,哪怕他们的值完全相等。id(object)函数是返回对象object在其生命周期内位于内存中的地址,id函数的参数类型是一个对象。

2、is和== 的区别

用is判断两个对象是否相等时,依据就是这个id值。
is与的区别就是,is是内存中的比较,而是值的比较

Reference:
1、https://blog.csdn.net/jy692405180/article/details/60881571
2、https://blog.csdn.net/djskl/article/details/25886187
3、https://iaman.actor/blog/2016/04/17/copy-in-python

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述
♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠

标签:python,对象,复制,模块,deepcopy,拷贝,copy,id
From: https://blog.csdn.net/2401_88244350/article/details/143324452

相关文章

  • 使用 Python 实现高效网页爬虫——从获取链接到数据保存
    前言在这个时代,网络爬虫已成为数据分析与信息收集不可或缺的技术之一。本文将通过一个具体的Python项目来介绍如何构建一个简单的网络爬虫,它能够自动抓取指定网站的文章链接、标题、正文内容以及图片链接,并将这些信息保存为CSV文件。目标网站一、准备工作在开始编写爬......
  • 将本地安装的Python库集成到Docker镜像
    1.确定本地库的位置和格式首先,你需要明确本地库的位置和格式。如果是Python库,它可能是以.whl(wheel格式)、.tar.gz(压缩包格式)或者是一个包含源代码的目录形式存在。2.使用COPY或ADD指令(对于简单的本地库文件)COPY指令:如果本地库是一个简单的文件(如.whl或.tar.gz),可......
  • python使用loguru入门
    自定义json格式fromloguruimportloggerimportjsonfromdatetimeimportdatetime#定义一个函数来创建JSON格式的日志defjson_log(level,message,**kwargs):log_entry={"time":datetime.now().isoformat(),"level":level.upper(),......
  • python毕设超市进销存管理系统程序+论文
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容一、选题背景关于超市进销存管理系统的研究,现有研究主要以大型企业的进销存管理为主,专门针对超市这一特定场景的进销存管理研究较少。在国内外的研......
  • Python程序:计算特定数列之和
    题目要求编写一个Python程序,计算数列$s=a+aa+aaa+aaaa+\ldots$的和,其中$a$是一个数字,数列中每个数都是由$a$重复组成,且重复次数逐渐增加。用户可以通过键盘控制数列中相加的数的个数。解题思路为了计算这个数列的和,我们需要首先理解数列的构成。每个数都......
  • python文件修改有没有办法警告通知
    在Python中设置文件修改的警告通知,可以通过几种不同的方法实现。以下是两种常见的方法:使用watchdog库进行实时监控:watchdog是一个跨平台的文件系统监控工具,它可以用来监控文件或目录的变化,如文件的创建、修改、删除等。你可以通过定义一个事件处理器来响应文件修改事件,并在事件......
  • 运行python常用语句记录(持续更新,欢迎讨论补充)
    代码整合标题后,直接点目录CMD常用语句记录查看信息(全部、环境、库)创建、运行虚拟环境库的操作安装库conda安装pip安装官网安装(自己下载安装)requirement.txt安装源代码安装导出库删除库更新库镜像源运行python文件python常用语句记录调用gpu或cpu小白记录,如有错......
  • Python 进行数据挖掘的算法介绍
    1.决策树决策树是一种用于分类和回归任务的监督学习算法。它通过树状结构来表示决策过程,每个内部节点表示一个属性上的测试,每个分支代表一个测试结果,每个叶节点代表一种分类结果。示例代码:fromsklearn.datasetsimportload_irisfromsklearn.treeimportDecisionTreeCl......
  • 终于弄懂了Python位置参数与关键字参数
    Python位置参数与关键字参数在Python函数的使用中,函数的参数是一种让调用者向函数传递信息的手段。函数可以通过参数接收外部提供的值,从而根据这些值执行特定的操作。本节我们将重点讲解位置参数和关键字参数两种参数类型,它们是定义和调用函数时最基础的参数形式。1.位置......
  • Python条件赋值:一种强大的控制流程方式
    在编程中,条件赋值是一种非常常见的操作,它允许我们在满足特定条件时对变量进行赋值。Python作为一种广泛应用的编程语言,自然也支持这种操作。本文将对Python中的条件赋值进行简要解读和分析。什么是条件赋值?条件赋值,顾名思义,就是在满足某个条件时进行的赋值操作。在Python中,我......