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 相关文章推荐
Python实现从url中提取域名的几种方法
Sep 26 Python
python解析xml文件实例分析
May 27 Python
Python使用Beautiful Soup包编写爬虫时的一些关键点
Jan 20 Python
Django小白教程之Django用户注册与登录
Apr 22 Python
python基础教程之Filter使用方法
Jan 17 Python
python实现给微信公众号发送消息的方法
Jun 30 Python
python3利用smtplib通过qq邮箱发送邮件方法示例
Dec 03 Python
Python3.7实现中控考勤机自动连接
Aug 28 Python
python自动识别文本编码格式代码
Dec 26 Python
pycharm开发一个简单界面和通用mvc模板(操作方法图解)
May 27 Python
Python使用OpenPyXL处理Excel表格
Jul 02 Python
如何用Python 加密文件
Sep 10 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
PHP学习之输出字符串(echo,print,printf,print_r和var_dump)
2011/04/17 PHP
主流PHP框架的优缺点对比分析
2014/12/25 PHP
php实现httpRequest的方法
2015/03/13 PHP
PHP使用数组依次替换字符串中匹配项
2016/01/08 PHP
浅析Yii2集成富文本编辑器redactor实例教程
2016/04/25 PHP
laravel学习教程之关联模型
2016/07/30 PHP
php函数式编程简单示例
2019/08/08 PHP
确保Laravel网站不会被嵌入到其他站点中的方法
2019/10/18 PHP
PHPUnit + Laravel单元测试常用技能
2019/11/06 PHP
php中Swoole的热更新实现代码实例
2021/03/04 PHP
广泛收集的jQuery拖放插件集合
2012/04/09 Javascript
js正则表达exec与match的区别说明
2014/01/29 Javascript
javascript实现分栏显示小技巧附图
2014/10/13 Javascript
JS修改iframe页面背景颜色的方法
2015/04/01 Javascript
Bootstrap实现响应式导航栏效果
2015/12/28 Javascript
JS加载器如何动态加载外部js文件
2016/05/26 Javascript
探讨AngularJs中ui.route的简单应用
2016/11/16 Javascript
JS switch判断 三目运算 while 及 属性操作代码
2017/09/03 Javascript
vue-cli axios请求方式及跨域处理问题
2018/03/28 Javascript
vue自定义全局共用函数详解
2018/09/18 Javascript
iView框架问题整理小结
2018/10/16 Javascript
详解Python使用tensorflow入门指南
2018/02/09 Python
python实现学生信息管理系统
2020/04/05 Python
python3使用pandas获取股票数据的方法
2018/12/22 Python
几个适合python初学者的简单小程序,看完受益匪浅!(推荐)
2019/04/16 Python
使用python远程操作linux过程解析
2019/12/04 Python
Python使用正则实现计算字符串算式
2019/12/29 Python
打包PyQt5应用时的注意事项
2020/02/14 Python
在pycharm中使用matplotlib.pyplot 绘图时报错的解决
2020/06/01 Python
Python实现一个简单的毕业生信息管理系统的示例代码
2020/06/08 Python
美国廉价机票预订网站:Cheapfaremart
2018/04/28 全球购物
中东地区为妈妈们提供一切的头号购物目的地:Sprii
2018/05/06 全球购物
2019年Java面试必问之经典试题
2012/09/12 面试题
新闻人物通讯稿
2014/10/09 职场文书
如何在C++中调用Python
2021/05/21 Python
Golang MatrixOne使用介绍和汇编语法
2022/04/19 Golang