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采集百度百科的方法
Jun 05 Python
Python开发中爬虫使用代理proxy抓取网页的方法示例
Sep 26 Python
Python爬虫实例爬取网站搞笑段子
Nov 08 Python
基于Django与ajax之间的json传输方法
May 29 Python
python获取命令行输入参数列表的实例代码
Jun 23 Python
Tensorflow 同时载入多个模型的实例讲解
Jul 27 Python
Python Opencv任意形状目标检测并绘制框图
Jul 23 Python
python实现输出一个序列的所有子序列示例
Nov 18 Python
python NumPy ndarray二维数组 按照行列求平均实例
Nov 26 Python
Python 限定函数参数的类型及默认值方式
Dec 24 Python
如何利用python web框架做文件流下载的实现示例
Jun 02 Python
用Python爬取LOL所有的英雄信息以及英雄皮肤的示例代码
Jul 13 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
MySQL连接数超过限制的解决方法
2011/07/17 PHP
PHP正则表达式之定界符和原子介绍
2012/10/05 PHP
PHP设置图片文件上传大小的具体实现方法
2013/10/11 PHP
php使用strtotime和date函数判断日期是否有效代码分享
2013/12/25 PHP
php禁止浏览器使用缓存页面的方法
2014/11/07 PHP
示例详解Laravel的注册重构
2016/08/14 PHP
JS去除字符串的空格增强版(可以去除中间的空格)
2009/08/26 Javascript
IE6/7/8/9不支持exec的简写方式
2011/05/25 Javascript
HTML+CSS+JS实现完美兼容各大浏览器的TABLE固定列
2015/04/26 Javascript
javascript实现动态统计图开发实例
2015/11/21 Javascript
跨域资源共享 CORS 详解
2016/04/26 Javascript
jquery删除table当前行的实例代码
2016/10/07 Javascript
JS冒泡事件与事件捕获实例详解
2016/11/25 Javascript
浅谈Angular4实现热加载开发旅程
2017/09/08 Javascript
javascript for循环性能测试示例
2019/08/07 Javascript
Vue+element+cookie记住密码功能的简单实现方法
2020/09/20 Javascript
原生JS实现拖拽功能
2020/12/16 Javascript
python函数参数*args**kwargs用法实例
2013/12/04 Python
Python使用QQ邮箱发送Email的方法实例
2017/02/09 Python
python 监测内存和cpu的使用率实例
2019/11/28 Python
python飞机大战pygame游戏之敌机出场实现方法详解
2019/12/17 Python
基于python计算并显示日间、星期客流高峰
2020/05/07 Python
django有哪些好处和优点
2020/09/01 Python
英国现代绅士品牌:Hackett
2017/12/17 全球购物
Feelunique德国官方网站:欧洲最大的在线美容零售商
2019/07/20 全球购物
俄罗斯电子产品、计算机和家用电器购物网站:OLDI
2019/10/27 全球购物
Haggar官网:美国男装品牌
2020/02/16 全球购物
上海微创软件面试题
2012/06/14 面试题
双语教学实施方案
2014/03/23 职场文书
小学生手册家长评语
2014/04/16 职场文书
蟋蟀的住宅教学反思
2014/04/26 职场文书
关心下一代工作先进事迹
2014/08/15 职场文书
社区娱乐活动方案
2014/08/21 职场文书
python基于tkinter制作无损音乐下载工具
2021/03/29 Python
使用numpy实现矩阵的翻转(flip)与旋转
2021/06/03 Python
从结婚开始的恋爱故事。小说《我的美好婚事》TV动画化决定
2022/04/07 日漫