深浅拷贝

在研究Python的深浅拷贝区别前需要先弄清楚以下的一些基础概念:

变量--引用--对象(可变对象,不可变对象)

切片(序列化对象)--拷贝(深拷贝,浅拷贝)

我是铺垫~

一、【变量--引用--对象】:

Python中一切皆对象,甚至连type本身都是type对象。

  1 >>> type(type(n1))
2 <class 'type'>

Python中的变量不同于与Java/c/c++不同,它是对象的引用,是动态型变量,数据类型无须提前声明,变量类型是根据对象的类型动态变化。

例如运行n=9,Python内部先在内存中找块地址来存储9,n只是对这个对象的引用,或者说将指针指向这个对象。

这里的整数对象9包含了两层含义:

1、数值为9

2、一个头部信息,告诉Python这是个int对象【可理解为一个指向int类型的指针】

小结:

变量是一个系统表的元素,拥有指向对象的连接的空间;

对象是被分配的一块内存,用来存储值;

引用是在变量赋值时自动形成的变量到对象的指针。

再来看下面的例子:

  1 >>> a = 3
2 >>> b = a
3 >>> id(a);id(b)
4 1627390480
5 1627390480
6 >>> del a
7 >>> b
8 3 >>> a = 5 >>> b 3

可以看出,a和b共享引用,指向同一个内存地址(其id完全相同),所以将变量a删除或者将a赋值为4,都对变量b的数值无影响。

上面的例子有一个局限,就是数值类型对象是不可改变的,如果换成列表和元组对象呢?

二、【可变对象--不可变对象】

Python中的可变对象:可以修改的对象,列表和字典。

Python中的不可变对象:一旦创建就不可以修改的对象,字符串、元组、整数。

  1 >>> L1 = [2,3,4]
2 >>> L2 = L1
3 >>> L2
4 [2, 3, 4]
5 >>> L1= [5,6]
6 >>> L2
7 [2, 3, 4]
8 >>> L1 = [1,2,3]
9 >>> L2 = L1
10 >>> L1[0] = 99
11 >>> L1;L2
12 [99, 2, 3]
13 [99, 2, 3]
14 #因为对象本身变了

如此一来,可变对象的变量共享引用就可能会有问题了(原本对源变量的修改,一不小心影响了其他的变量引用)。所以针对这种情景,才有了深浅copy。

那么如果不想改变上面L2的值有两种作法:切片和copy模块。

  1 >>> L1
2 [99, 2, 3]
3 >>> L2 = L1[:]
4 >>> L1,L2
5 ([99, 2, 3], [99, 2, 3])
6 >>> id(L1);id(L2)
7 3089554433480
8 3089554433992
9 >>> L1[0] = 100
10 >>> L1;L2
11 [100, 2, 3]
12 [99, 2, 3]

拷贝

切片技术的应用范围:序列对象,即列表、字符串、元组。

注:序列是一类基本数据类型(字符串/列表/元组)的统称,这些数据类型都含有一些共同的特性。

切片不能应用于字典,对于字典只有dic.copy()方法和dic.deepcopy()方法。

  1 >>> dic = {'name':'bolen','age':18}
2 >>> [item for item in dir(dic) if not item.startswith('__')]
3 ['clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']
4
5 #上面的语法和三元运算一样,x = 1 if n >2 else 3(或x = [2,1][n>2]),都是Python中的语法糖。
  1 >>> import copy
2 >>> L3 = copy.copy(L1)
3 >>> L4 = copy.deepcopy(L1)
4 >>>

上面铺垫了这么多,就是想说深浅拷贝,既可应用于序列对象也可用于字典。

【浅拷贝】

浅拷贝只拷贝顶层对象或者说父级对象。

【深拷贝】

深拷贝是拷贝所有对象,包括顶级对象和镶套对象,或者说拷贝所有父对象和子对象。

闲言少叙,show code:

  1 >>> n1
2 {'k1': 'lilei', 'k3': ['yy', 456], 'k2': 123}
3 >>> n4 = n1
4 >>> n2= copy.copy(n1)
5 >>> n3 = copy.deepcopy(n1)
6 >>> n1;n2;n3;n4
7 {'k1': 'bboo', 'k3': ['yy', 456], 'k2': 123}
8 {'k1': 'bboo', 'k3': ['yy', 456], 'k2': 123}
9 {'k1': 'bboo', 'k3': ['yy', 456], 'k2': 123}
10 {'k1': 'bboo', 'k3': ['yy', 456], 'k2': 123}
11 >>> id(n1);id(n2);id(n3);id(n4)
12 3089553992072
13 3089554432904
14 3089554359368
15 3089553992072
16 #深浅拷贝内存地址和源对象都不一样。
17 >>> n1['k1'] = 'bolen'
18 >>> n1;n2;n3;n4
19 {'k1': 'bolen', 'k3': ['yy', 456], 'k2': 123}
20 {'k1': 'bboo', 'k3': ['yy', 456], 'k2': 123}
21 {'k1': 'bboo', 'k3': ['yy', 456], 'k2': 123}
22 {'k1': 'bolen', 'k3': ['yy', 456], 'k2': 123}
23 >>> n1['k3'][1]=789
24 >>> n1;n2;n3;n4
25 {'k1': 'bolen', 'k3': ['yy', 789], 'k2': 123}
26 {'k1': 'bboo', 'k3': ['yy', 789], 'k2': 123}
27 {'k1': 'bboo', 'k3': ['yy', 456], 'k2': 123}
28 {'k1': 'bolen', 'k3': ['yy', 789], 'k2': 123}
29 #当有多层镶套时,源对象改变后,浅拷贝和共享引用的值都变了,而深拷贝没有变。

【总结】

深浅拷贝都是对源对象的复制,占用不同的内存空间
如果源对象只有一级目录的话,源做任何改动,不影响深浅拷贝对象
如果源对象不止一级目录的话,源做任何改动,都要影响浅拷贝,但不影响深拷贝
序列对象的切片其实是浅拷贝,即只拷贝顶级的对象

Python基础【3】:Python中的深浅拷贝解析的更多相关文章

  1. python基础知识5——赋值与深浅拷贝——整数和字符串,列表元组字典

    深浅copy 一.数字和字符串 对于 数字 和 字符串 而言,赋值.浅拷贝和深拷贝无意义,因为其永远指向同一个内存地址. 1 import copy 2 # ######### 数字.字符串 #### ...

  2. Core Python Programming一书中关于深浅拷贝的错误

    该书关于深浅拷贝的论述: 6.20. *Copying Python Objects and Shallow and Deep Copies "when shallow copies are ...

  3. python基础-3 集合 三元运算 深浅拷贝 函数 Python作用域

    上节课总结 1 运算符 in 字符串 判断  : “hello” in "asdasfhelloasdfsadf" 列表元素判断:"li" in ['li', ...

  4. 天啦噜!仅仅5张图,彻底搞懂Python中的深浅拷贝

    Python中的深浅拷贝 在讲深浅拷贝之前,我们先重温一下 is 和==的区别. 在判断对象是否相等比较的时候我们可以用is 和 == is:比较两个对象的引用是否相同,即 它们的id 是否一样 == ...

  5. Python 中的深浅拷贝

    Python 中的深浅拷贝 参考文献:https://blog.csdn.net/lnotime/article/details/81194633 参考文献:https://blog.csdn.net ...

  6. 二十一. Python基础(21)--Python基础(21)

    二十一. Python基础(21)--Python基础(21) 1 ● 类的命名空间 #对于类的静态属性:     #类.属性: 调用的就是类中的属性     #对象.属性: 先从自己的内存空间里找名 ...

  7. js中的深浅拷贝

    js中的深浅拷贝 js中有深拷贝.浅拷贝一说,所谓的深浅拷贝是针对value类型为引用类型(函数.对象.数组)而言的,大概理解的就是: 浅拷贝: 拷贝出的对象c和原始对象o,c和o在key对应的val ...

  8. Python中的深浅拷贝

    1.什么是深浅拷贝? python中一切皆对象,python中的数字.字符串.元组等,如果存放在了内存中,这部分内存里面的内容是不会改变的,但是也有情况,内存中存放了可变对象,比如说列表和字典,他们的 ...

  9. Python中的深浅拷贝,赋值及引用

    简单来说,若对象a中存的是列表或字典等可变对象,b对a的浅拷贝只是对对象第一层的复制,修改b第二层的元素仍然会影响两个对象. 深拷贝则是不会影响原来的对象. import copy.copy() 浅拷 ...

随机推荐

  1. Kubernetes学习之路(十五)之Ingress和Ingress Controller

    目录 一.什么是Ingress? 1.Pod 漂移问题 2.端口管理问题 3.域名分配及动态更新问题 二.如何创建Ingress资源 三.Ingress资源类型 1.单Service资源型Ingres ...

  2. ubuntu 图形化界面 gui 桌面版 root登录 sorry,that didn't work.please try again! 抱歉,认证失败。请重试

    出现这种问题,用下面的方法就行了 https://jingyan.baidu.com/article/bad08e1e224b2709c85121f1.html 而且我发现,因为我用的是英文版的ubu ...

  3. React——event

    1.绑定在React元素上的事件与绑定在DOM元素上的事件非常相似,但是也有一个不同的地方 React事件使用驼峰命名法命名 //在HTML中 <button onclick='handle() ...

  4. eclipse—Maven项目打包成exe

    1.下载打包工具j2ewiz  友情连接:https://pan.baidu.com/s/1Rcoqix5QcrJVI1of9h7qbQ提取码:vqn1 2.选中想要打包的文件,右击—Export 按 ...

  5. POSTMAN接口测试get和post

    GET 1.在URL栏里输入想要访问的IP,并点击旁边的Params,对具体要查询的内容进行复制,百度对要查询的字段的key是wd 这里将参数值的勾选取消掉可以看到URL内容的变化,查询字段消失 2. ...

  6. myeclipse激活后server不能用问题

    一般是由于激活失败造成的,这种问题就卸了重新安装吧,目前还没有找到合理的方法解决,这个还真的看哥们的运气了,我是装了不下5遍才激活成功的,一般情况下,在激活的时候 出现下图的情况,Usercode写好 ...

  7. 【SIKIA计划】_07_Unity3D游戏开发-坦克大战笔记

    [新增分类][AudioClips]音频剪辑[AudioMixers]音频混合器[Editor][Fonts]字体[Materials]材质[Models]模型[Standard Assets] [渲 ...

  8. vim文本编辑工具(全)

    VIM文本编辑工具 编辑模式 i    在当前字符前插入I   在光标所在的行首插入a 在当前字符后插入A 在光标所在行尾插入o 在当前行的下一行插入新的一行O 在当前行的上一行插入新的一行 s   ...

  9. C程序员必读的 3 本书

    C程序员必读的 3 本书 原创: Martin 老师  公众号:零基础零障碍学习C语言 勿用质疑,今天来看这篇文章的朋友都是准备学好C语言的朋友,大家想学好C语言的迫切性,就好比Martin老师等着元 ...

  10. SICP读书笔记 3.4

    SICP CONCLUSION 让我们举起杯,祝福那些将他们的思想镶嵌在重重括号之间的Lisp程序员 ! 祝我能够突破层层代码,找到住在里计算机的神灵! 目录 1. 构造过程抽象 2. 构造数据抽象 ...