直接赋值: 对象的引用,也就是给对象起别名

很多人学习python,不知道从何学起。
很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手。
很多已经做案例的人,却不知道如何去学习更加高深的知识。
那么针对这三类人,我给大家提供一个好的学习平台,免费领取视频教程,电子书籍,以及课程的源代码!
QQ群:1097524789

浅拷贝: 拷贝父对象,但是不会拷贝对象的内部的子对象。

深拷贝: 拷贝父对象. 以及其内部的子对象

在之前的文章中,提到可变对象和不可变对象,接下来也是以这两者的区别进行展开

直接赋值

对于可变对象和不可变对象,将一个变量直接赋值给另外一个变量,两者 id 值一致,其实本质上是将变量量绑定到对象的过程.

>>> a=1
>>> b=a
>>> id(a) == id(b)
True
>>> c="string"
>>> d=c
>>> id(c) == id(d)
True
>>> e=[1,2,3]
>>> f=e
>>> id(e)==id(f)
True

关于修改新变量的值,对原有变量会产生的影响,在 可变对象和不可变对象 中也做了讲述,这里通过几个例子,重新温习一下

不可变对象

>>> x=1
>>> y=x
>>> id(x)==id(y)
True
>>> id(1)==id(y)
True
>>>>>> id(x)
1500143776
>>> y=y+1
>>> y
2
>>> x
1
>>> id(x)==id(y)
False
>>> id(y)
1500143808
>>> id(x)
1500143776

对于不可变对象,修改赋值后的新变量,不会对原有变量造成任何影响.为什么出现这种现象呢?因为不可变对象一旦创建之后就不允许被改变.后面对 y 进行的操作,其实是重新创建一个对象并绑定的结果:

可变对象

>>> m=[1,2,3]
>>> n=m
>>> id(n)==id(m)
True
>>> id(m)
1772066764488
>>> id(n[0])
1772066764656
>>> n[0]=4
>>> n
[4, 2, 3]
>>> m
[4, 2, 3]
>>> id(n)==id(m)
True
>>> id(m)
1772066764488

对于可变对象,修改赋值后的变量,会对原有的变量造成影响,会导致其 value 值的改变,但是其 id 值保持不变

从上图不难看出,这个时候的 id(n[0]) 的值,和未修改前的 id 值应该不一样,可以输出看一下

>>>id(n[0])
1772066764752 # 最初没有修改前是  1772066764656

n[0] 修改前后为什么 id 值出现改变呢? 首先需要明确一点 n[0] 绑定的是一个不可变对象,在文章的最初提到, 不可变对象一旦创建就不允许修改 .显然对 n[0] 进行修改,不能在绑定对象的内存上进行修改,那如何实现重新赋值呢?只能创建一个新的对象 4 ,然后将 n[0] 绑定到新的对象

浅拷贝和深拷贝

先看一下官方文档的定义

The difference between shallow and deep copying is only relevant for compound objects (objects that contain other objects, like lists or

class instances).

A shallow copy constructs a new compound object and then (to the

extent possible) inserts the same objects into it that the

original contains.

A deep copy constructs a new compound object and then, recursively,inserts copies into it of the objects found in the original.

从文档中不难看出,上面提到深拷贝和浅拷贝两者区别在于在复合对象,那接下来也只讨论复合对象.

浅拷贝

注意到官方文档也提到对浅拷贝和深拷贝的定义,从上文中不难看出, 浅拷贝构建一个复合对象,然后将原有复合对象包含的对象插入到新的复合对象中

从上图不难看出, 浅拷贝后,新复合对象包含的对象(可变或者不可变)的 id 值和原有对象包含的对象的 id 值相同

看一下具体例子:

>>> import copy
>>> a=[1,2,[3,4]]
>>> b=copy.copy(a)
>>> id(b[0])==id(a[0])
True
>>> id(b[2])==id(a[2])
True
>>> id(b[2][0])==id(a[2][0])
True

现在让我们试着修改一下浅拷贝后的 b 的值,在修改前,可以先思考一下,如果修改 b[0] 可能会发生什么?

由于 b[0] = 1 ,很显然 1 属于不可变对象,那么根据对不可变变量修改的规则,则 b[0] 会绑定到新的变量上,而 a[0] 的由于没有修改,则保持不变,真的是这样吗?让我们验证一下

>>> b[0]=5
>>> b
[5, 2, [3, 4]]
>>> a
[1, 2, [3, 4]]

接下来我们要尝试修改一下 b[2] ,由于 b[2] 绑定的对象是 list ,属于可变对象,按照上面说的可变对象修改的规则,则修改后的 b[2] 的 id 值保持不变,但是其 value 值会发生改变. 同样的让我们通过例子验证一下

>>> id(b[2])
4300618568
>>> b[2][0]=6
>>> id(b[2])
4300618568
>>> b
[5, 2, [6, 4]]
>>> a
[1, 2, [6, 4]]

由于 b[2] 和 a[2] 绑定同一个可变对象,很显然对 b[2] 的修改同样会映射到 a[2] 上

深拷贝

深拷贝构建一个复合对象,然后递归的将原有复合包含的对象的副本插入到新的复合对象中

若上图所示, 深拷贝后,新的复合对象包含的对象,若对象为不可变对象,则 id 值保持不变,若对象为可变对象,则 id 值发生改变

看一个例子:

>>> import copy
>>> a=[1,2,[3,4]]
>>> b=copy.deepcopy(a)
>>> id(b[0])==id(a[0])
True
>>> id(b[2])==id(a[0])
False
>>> id(b[2][0])==id(a[2][0])
True

接下来让我们修改一下变量 b ,这里就不在修改不可变对象 b[0] 和 b[1] 了,因为结果很明显,对 a 不会产生任何影响,我们来修改 b[2] ,那么修改 b[2] 会对 a[2] 产生影响吗?很明显答案是不会,因为深拷贝就相当于克隆出了一个全新的个体,两者不再有任何关系

>>> b[2][0]=5
>>> b
[1, 2, [5, 4]]
>>> a
[1, 2, [3, 4]]

【Python】直接赋值,深拷贝和浅拷贝相关推荐

  1. python怎么避免浅拷贝_详谈Python中的深拷贝和浅拷贝

    在平时工作中,经常涉及到数据的传递,在数据传递使用过程中,可能会发生数据被修改的问题.为了防止数据被修改,就需要在传递一个副本,即使副本被修改,也不会影响原数据的使用.为了生成这个副本,就产生了拷贝. ...

  2. python中的深拷贝与浅拷贝

    浅拷贝的时候,修改原来的对象,深拷贝的对象不会发生改变. 对象的赋值 对象的赋值实际上是对象之间的引用:当创建一个对象,然后将这个对象赋值给另外一个变量的时候,python并没有拷贝这个对象,而只是拷 ...

  3. python中关于深拷贝和浅拷贝的详解

    python中关于深拷贝和浅拷贝的详解 概述 在python的语法中,有两种变量的拷贝方式 一种是深拷贝,一种是浅拷贝 我们先说深拷贝 语法 这里需要通过导入系统的copy模块中的deepcopy才可 ...

  4. python编程(深拷贝和浅拷贝)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 今天工作中遇到了深拷贝和浅拷贝的问题,特地记录一下,以前我们写python代码的时候是这样的, ...

  5. 关于python中的深拷贝和浅拷贝的总结

    可变对象和不可变对象 了解深拷贝和浅拷贝之前你得先知道什么时可变对象什么是不可变对象传送门 深拷贝和浅拷贝拷贝不可变对象时 import copy a = 1 b = copy.copy(a) c = ...

  6. python教程:深拷贝与浅拷贝的具体区别在哪里

    在python中,对象赋值实际上是对象的引用.当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用 一般有三种方法, alist=[1,2,3,[& ...

  7. python中深拷贝和浅拷贝_**Python中的深拷贝和浅拷贝详解

    甚至连type其本身都是对象,type对象 Python中变量与C/C++/Java中不同,它是指对象的引用,Python是动态类型,程序运行时候,会根据对象的类型 来确认变量到底是什么类型. 单独赋 ...

  8. python笔记:深拷贝与浅拷贝

    =号赋值,相当于一个引用 浅拷贝:只是最外面的一层的拷贝,内部的元素都只是拷贝了一个引用 深拷贝:全拷贝,不管是外面一层还是里面的所有层.都进行了拷贝.

  9. python深浅拷贝的底层理解_理解python中的深拷贝与浅拷贝

    python中浅拷贝和深拷贝的区别如下: 1. copy.copy 等价于切片[:]  浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象.2个列表是不同的,但是子列表指向的仍然是同一个地址 2. co ...

最新文章

  1. MXNet中依赖库介绍及简单使用
  2. 判断出栈顺序的合法性(面试题)
  3. 怎么用python处理excel文件-python处理Excel文件
  4. Programming Computer Vision with Python (学习笔记十)
  5. 2021年图机器学习有哪些新突破?麦吉尔大学博士后一文梳理展望领域趋势
  6. Java并发编程(一)线程的各种创建方式
  7. React Native的安装和初始化(android /ios)
  8. PMP读书笔记(第2章)
  9. 现代软件工程讲义 0 课程概述
  10. 荒野行动服务器维护啥时好,荒野行动服务器真的极差
  11. 日历报表_在报表中实施不同的日历
  12. ECMAScript 6 开篇准备
  13. Mac系统如何安装php,MAC系统如何快速安装php
  14. MT艾宾浩斯背单词(附带主程序)
  15. SQL Server 日期+4位流水号
  16. Eclipse-cpp-2022-03下载地址
  17. Python爬虫之爬取酷狗音乐
  18. openbsd运行Linux应用程序,OpenBSD上的服务管理程序rcctl
  19. 2014年中款MacBook Pro 更换CPU散热硅脂再战5年
  20. 如何做好电脑重要文件数据的备份

热门文章

  1. (干货).NET开发丰富的公共类库助你事半功倍(供下载免费使用)
  2. 高效数据序列化的工具 FlatBuffers 的初体验
  3. Django笔记(1)
  4. ArrayDeque 双端队列
  5. 物化视图常用维护操作
  6. 分享8个超棒的免费高质量图标搜索引擎
  7. 【思维智慧】007.利用贪婪的人身上的破绽
  8. 分布式数据库中间件 MyCat 安装及使用
  9. java中什么是释放已经持有的锁_java多线程什么时候释放锁
  10. WinForm和WPF使用log4net