Python的赋值、深拷贝与浅拷贝的区别详解


Posted in Python onFebruary 12, 2020

在python中,给一个对象赋值,实际上就是对象对内存空间存储的值的引用。当我们把对象赋值给另一个变量的时候,这个变量并没有拷贝这个对象,而只是拷贝了这个对象的引用而已。

一般情况下我们会通过三种方法来实现拷贝对象的引用。

Python直接赋值

直接赋值,默认浅拷贝传递对象的引用而已,原始列表改变,被赋值的变量也会做相同的改变。其实就是对‘对象'的引用

示例:

>>> list_demo = [2, 4, 6]
>>> a = list_demo
>>> print(a)
[2, 4, 6]
>>> id(list_demo)
65006808
>>> id(a)
65006808
>>> list_demo.append(8)
>>> print(list_demo)
[2, 4, 6, 8]
>>> print(a)
[2, 4, 6, 8]
>>> id(list_demo)
65006808
>>> id(a)
65006808
>>>

通过 id() 函数我们可以得出,变量 list_demo 与 a 指向的都是同一个内存空间地址,当被赋值的 list_demo改变,被赋值的 a 同样会做相同的改变。这种现象普遍存在于 Python 之中,这种赋值的方式实现了 “假装” 拷贝,真实的情况还是两个变量和同一个对象之间的引用关系。

Python浅拷贝

import copy 模块的 copy.copy() 方法,该方法只拷贝父对象,没有拷贝子对象。且浅拷贝是创建一块新的内存空间,但是内存空间内的元素的地址均是父对象元素的地址的拷贝。所以当父对象内部的子对象发生改变时,拷贝对象的内部的子对象也会跟着改变。

示例:

>>> list_demo1 = [2, 4, 6, [8, 10]]
>>> a = list_demo1
>>> print(list_demo1)
[2, 4, 6, [8, 10]]
>>> print(a)
[2, 4, 6, [8, 10]]
>>>
>>>
>>> import copy
>>> b = copy.copy(list_demo1)
>>> id(list_demo1)
65103472
>>> id(b)
6011200
>>> list_demo1.append(12)
>>> print(list_demo1)
[2, 4, 6, [8, 10], 12]
>>> list_demo1[3]
[8, 10]
>>>
>>>
>>>
>>> list_demo1[3].append('hello')
>>> print(list_demo1)
[2, 4, 6, [8, 10, 'hello'], 12]
>>> print(b)
[2, 4, 6, [8, 10, 'hello']]
>>> list_demo1[3]
[8, 10, 'hello']
>>> b[3]
[8, 10, 'hello']
>>>
>>>
>>>
>>> id(list_demo1)
65103472
>>> id(b)
6011200
>>> id(list_demo1[3])
64679128
>>> id(b[3])
64679128
>>>

从上述代码可以看出,在执行浅拷贝的时候,浅拷贝实际上只拷贝引用,不拷贝内容。同时,浅拷贝会针对父对象的子对象进行判断,当父对象的子对象发生改变时,拷贝对象内的子对象同时也跟着改变。

Python深拷贝

import copy 模块的 copy.deepcopy() 方法,深拷贝与浅拷贝相反,就是彻彻底底的拷贝,完全的拷贝了父对象及子对象,同时指向一个新的内存空间地址。此时,虽然源对象与拷贝对象的内容是一样的,但是不管针对谁进行改动,另一个是丝毫不会受到影响的。

>>> list_demo2 = [2,3,4]

>>> c= copy.deepcopy(list_demo2)

>>> print(list_demo2)

[2, 3, 4]

>>> print(c)

[2, 3, 4]

>>> id(list_demo2)

6011440

>>> id(c)

6012440

>>> list_demo2.append(['a','b'])

>>> c.append([5,6])

>>> print(list_demo2)

[2, 3, 4, ['a', 'b']]

>>> print(c)

[2, 3, 4, [5, 6]]

>>> list_demo2[3].append('c')

>>> c[3].append(7)

>>> print(list_demo2)

[2, 3, 4, ['a', 'b', 'c']]

>>> print(c)

[2, 3, 4, [5, 6, 7]]

>>>

从上述代码示例可以看出 list_demo2 与 c 相互独立,无论 list_demo2 与 c本身进行了修改,或者各自的子对象进行了修改 都没有互相影响。

总结

Python赋值

赋值的本质就是将一个对象的内存空间地址赋值给一个变量,让变量指向该内存空间地址。

Python浅拷贝

浅拷贝是拷贝了源对象的引用,并创建了一个新的内存空间地址。但是引用的对象的子对象的地址仍然是源对象的,所以当源对象的子对象发生改变时,拷贝对象内的子对象同时也跟着改变。

Python深拷贝

深拷贝就是彻底的拷贝,完全的拷贝了父对象及子对象,同时指向一个新的内存空间地址。源对象与拷贝对象之间的修改互不影响。

更多关于Python的赋值、深拷贝与浅拷贝的区别文章请查看下面的相关链接

Python 相关文章推荐
Python2.x版本中基本的中文编码问题解决
Oct 12 Python
EM算法的python实现的方法步骤
Jan 02 Python
Python使用requests及BeautifulSoup构建爬虫实例代码
Jan 24 Python
PyTorch CNN实战之MNIST手写数字识别示例
May 29 Python
从0开始的Python学习014面向对象编程(推荐)
Apr 02 Python
python实现爬取百度图片的方法示例
Jul 06 Python
Python日志无延迟实时写入的示例
Jul 11 Python
python实现windows倒计时锁屏功能
Jul 30 Python
Python 中由 yield 实现异步操作
May 04 Python
Django通过设置CORS解决跨域问题
Nov 26 Python
如何使用Python进行PDF图片识别OCR
Jan 22 Python
python os.listdir()乱码解决方案
Jan 31 Python
解决pyCharm中 module 调用失败的问题
Feb 12 #Python
Python写出新冠状病毒确诊人数地图的方法
Feb 12 #Python
pycharm通过ssh连接远程服务器教程
Feb 12 #Python
python日期与时间戳的各种转换示例
Feb 12 #Python
Python使用uuid库生成唯一标识ID
Feb 12 #Python
将python文件打包exe独立运行程序方法详解
Feb 12 #Python
Python打包模块wheel的使用方法与将python包发布到PyPI的方法详解
Feb 12 #Python
You might like
雄兵连:天使彦天使彦为爱折翼,彦和炙心同时念动的誓言!
2020/03/02 国漫
phpmyadmin config.inc.php配置示例
2013/08/27 PHP
php+mysqli实现将数据库中一张表信息打印到表格里的方法
2015/01/28 PHP
PHP调试函数和日志记录函数分享
2015/01/31 PHP
php银联网页支付实现方法
2015/03/04 PHP
PHP引用返回用法示例
2016/05/28 PHP
PHP命名空间与自动加载类详解
2018/09/04 PHP
JavaScript 继承使用分析
2011/05/12 Javascript
jQuery $.get 的妙用 访问本地文本文件
2012/07/12 Javascript
JavaScript 性能优化小结
2015/10/12 Javascript
js 判断一组日期是否是连续的简单实例
2016/07/11 Javascript
jQuery实现级联下拉框实战(5)
2017/02/08 Javascript
JS实现简易刻度时钟示例代码
2017/03/11 Javascript
基于Vue2.0的分页组件
2017/03/16 Javascript
JS原生带小白点轮播图实例讲解
2017/07/22 Javascript
element ui 对话框el-dialog关闭事件详解
2018/02/26 Javascript
Angular5中调用第三方js插件的方法
2018/02/26 Javascript
NodeJS 实现多语言的示例代码
2018/09/11 NodeJs
vue项目上传Github预览的实现示例
2018/11/06 Javascript
Node使用Selenium进行前端自动化操作的代码实现
2019/10/10 Javascript
[00:43]FTP典藏礼包 DOTA2三大英雄霸气新套装
2014/03/21 DOTA
Python列表生成器的循环技巧分享
2015/03/06 Python
python制作爬虫并将抓取结果保存到excel中
2016/04/06 Python
Python微信库:itchat的用法详解
2017/08/14 Python
python机器学习实战之树回归详解
2017/12/20 Python
Python打包方法Pyinstaller的使用
2018/10/09 Python
用Python实现筛选文件脚本的方法
2018/10/27 Python
Python直接赋值、浅拷贝与深度拷贝实例分析
2019/06/18 Python
深入了解Python iter() 方法的用法
2019/07/11 Python
python实现大文件分割与合并
2019/07/22 Python
django如何实现视图重定向
2019/07/24 Python
美国隐形眼镜零售商:LensPure
2019/03/10 全球购物
俄罗斯连接商品和买家的在线平台:goods.ru
2020/11/30 全球购物
高中家长寄语
2014/04/02 职场文书
《蜗牛的奖杯》教后反思
2014/04/24 职场文书
2016年教师反腐倡廉心得体会
2016/01/13 职场文书