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

文章目录:

  • 一、copy模块的介绍
    • 1、copy模块
  • 二、copy模块的使用
  • 拓展说明:
    • 1、id( )函数的使用
    • 2、is和== 的区别

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 copyclass 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中copy模块的使用,深拷贝和浅拷贝相关推荐

  1. Python中list的复制及深拷贝与浅拷贝探究

    在Python中,经常要对一个list进行复制.对于复制,自然的就有深拷贝与浅拷贝问题.深拷贝与浅拷贝的区别在于,当从原本的list复制出的list之后,修改其中的任意一个是否会对另一个造成影响,即这 ...

  2. Python中copy,deepcopy,浅拷贝(“=”)和深拷贝(“copy.deepcopy()”)

    python中对于对象的拷贝分为浅拷贝(copy)和深拷贝(deepcopy)两种方式.其中浅拷贝由"="完成.而深拷贝由copy模块中deepcopy()函数担任. 浅拷贝和深拷 ...

  3. Python中copy()和deepcopy()的区别

    同样是copy,二者有什么不同呢今天我们就一探究竟!!! 关于copy()和deepcopy()的第一篇博客 初学编程的小伙伴都会对于深浅拷贝的用法有些疑问,今天我们就结合python变量存储的特性从 ...

  4. Python中collections模块

    目录 Python中collections模块:模块实现了特定目标的容器,以提供Python标准内建容器 dict.list.set.tuple 的替代选择. Counter:字典的子类,提供了可哈希 ...

  5. Python 中的模块和包

    原文引至:前端小吉米 对于python中的模块和包, 我简直就想说, js nmlgb 就是一个 trash... 在前端写js根本就没有什么模块和包, 全部都是全局... 真lj... 畅快了. 写 ...

  6. python中copy和deepcopy详细区别

    python中copy和deepcopy 在 python 中,标识一个对象唯一身份的是:对象的id(内存地址),对象类型,对象值. deepcopy是真正意义上的复制,深拷贝,被复制对象完全复制一遍 ...

  7. python学习 - copy模块的浅复制(copy)与深复制(deepcopy)

    python学习 - copy模块的浅复制(copy)与深复制(deepcopy) 简介 copy.copy()详解 copy.deepcopy()详解 简介 在使用列表或者字典进行传递参数的时候,可 ...

  8. python sys模块作用_浅谈Python中的模块

    模块 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式.在Python中,一个.py文件就称之为一个模块(Mod ...

  9. python中Scipy模块求取积分

    python中Scipy模块求取积分的方法: SciPy下实现求函数的积分的函数的基本使用,积分,高等数学里有大量的讲述,基本意思就是求曲线下面积之和. 其中rn可认为是偏差,一般可以忽略不计,wi可 ...

最新文章

  1. Javascript绘图
  2. DFS分布式文件系统 不同用户访问不同服务器修改同一文件 解决方案
  3. Windows核心编程 第四章 进程(上)
  4. scala中断循环代码示例
  5. [Abp 源码分析]权限验证
  6. OenLayers 事件注册
  7. elasticsearch 批量插入
  8. h5问卷调查 html模版,问卷调查H5模板制作流程
  9. 802.11n无线网卡驱动linux,Ubuntu 无线网卡驱动安装教程
  10. 高数 | 【微分方程】技巧性例题 及 李林880详解
  11. 百位LOL英雄联盟角色合集
  12. Docker 安装可视化管理工具Portainer
  13. IDEA 远程断点调试
  14. Batch Normalization原理与实战
  15. 一个简单的shell脚本--判断网段主机IP存活情况
  16. BUUCTF做题小结
  17. 2017年丽江教师计算机网络培训,丽江计算机网络技术学校
  18. 免费数据集 人工智能训练方面
  19. 微软最新的 Web 开发工具WebMatrix的简单介绍及安装
  20. ASEMI整流桥GBU1510参数,GBU1510规格,GBU1510封装

热门文章

  1. 成功计算出文本类单词的概率
  2. 解决Missing artifact com.sun:tools:jar:1.5.0方法
  3. 【Android】Android 设置Activity窗体 不显示标题和全屏显示
  4. python语言程序设计基础第二版答案-python语言程序设计基础(第二版)第五章答案随笔...
  5. 退出python命令行-退出python命令
  6. python打开文件不存在-Python判断文件是否存在的三种方法
  7. python怎么读取列表-python读入列表
  8. python3.7安装turtle步骤-Python3 turtle安装和使用教程
  9. 学python需要什么文化基础-和尧名大叔一起从0开始学Python编程-循环
  10. python自学路线-零基础Python学习路线,小白的进阶之路!