Python深拷贝与浅拷贝用法实例分析


Posted in Python onMay 05, 2019

本文实例讲述了Python深拷贝与浅拷贝用法。分享给大家供大家参考,具体如下:

1、对象的赋值

对象的赋值实际上是对象之间的引用:当创建一个对象,然后将这个对象赋值给另外一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用。

当对对象做赋值或者是参数传递或者作为返回值的时候,总是传递原始对象的引用,而不是一个副本。如下所示:

在python中将一个变量赋值给另一个变量,传递的是引用.无论是a的内层变化还是外层变化,b都会发生同样的变化.因为b和a指向了同一个引用.类似于c语言中的同一片内存地址.

#coding=utf-8
a = [1,2,3,['a','b','c']]
b = a
print('*'*50)
print('--- b = a ---')
print('a = %s'%a)
print('b = %s'%b)
a.append(4)
print('--- 外层a增加了元素4 ---')
print('a = %s'%a)
print('b = %s'%b)
print('--- 内层增加了元素"d" ---')
a[3].append('d')
print('a = %s'%a)
print('b = %s'%b)

运行结果:

**************************************************
--- b = a ---
a = [1, 2, 3, ['a', 'b', 'c']]
b = [1, 2, 3, ['a', 'b', 'c']]
--- 外层a增加了元素4 ---
a = [1, 2, 3, ['a', 'b', 'c'], 4]
b = [1, 2, 3, ['a', 'b', 'c'], 4]
--- 内层增加了元素'd' ---
a = [1, 2, 3, ['a', 'b', 'c', 'd'], 4]
b = [1, 2, 3, ['a', 'b', 'c', 'd'], 4]

2、对象的复制

当你想修改一个对象,而且让原始的对象不受影响的时候,那么就需要使用到对象的复制,对象的复制可以通过三种方法实现:

a、 使用切片操作进行拷贝 - -slice operation

(注:切片技术应用于所有的序列,包括:列表、字符串、元祖 ,但切片不能应用于字典。对字典只能使用D.copy()方法或D.deepcopy()方法.)

b、 使用工厂函数进行拷贝,list / dir / set - -factoryfunction

c、 copy.copy()?use copymodule

在复制的时候,使用的是浅拷贝,复制了对象,但是对象中的元素,依然使用引用。

如下所示:

a = [1,2,3,['a','b','c']]

#coding=utf-8
import copy
#1.切片操作
print('--- 切片操作 ---')
b = a[:]
print('a = %s\tid(a) = %s'%(a,id(a)))
print('b = %s\tid(b) = %s'%(b,id(b)))
#2.使用工厂函数
print('--- 使用工厂函数 ---')
c = list(a)
print('a = %s\tid(a) = %s'%(a,id(a)))
print('c = %s\tid(c) = %s'%(c,id(c)))
#3.copy.copy()
print('--- copy.copy() ---')
d = copy.copy(a)
print('a = %s\tid(a) = %s'%(a,id(a)))
print('d = %s\tid(d) = %s'%(d,id(d)))

运行结果:

--- 切片操作 ---
a = [1, 2, 3, ['a', 'b', 'c']]  id(a) = 140676047022088
b = [1, 2, 3, ['a', 'b', 'c']]  id(b) = 140676047021320
--- 使用工厂函数 ---
a = [1, 2, 3, ['a', 'b', 'c']]  id(a) = 140676047022088
c = [1, 2, 3, ['a', 'b', 'c']]  id(c) = 140676047101640
--- copy.copy() ---
a = [1, 2, 3, ['a', 'b', 'c']]  id(a) = 140436217635720
d = [1, 2, 3, ['a', 'b', 'c']]  id(d) = 140436217656904

在使用浅拷贝的时候,发现引用的id都是相同的,但是字符串的id却发生了变化,是因为在python中,字符串是不可变的,从而在每次进行修改的时候,都是新建一个对象,从而引用发生了变化.

在不可变类型中,数字和字符串都是不可变类型,从而在每次修改的时候,都是新创建一个对象。

3、模块

核心模块:copy

浅拷贝和深拷贝的操作都可以在copy模块中找到,其实copy模块中只有两个函数可用,copy()进行浅拷贝操作,而deepcopy()进行深拷贝操作.

如下所示:

#coding=utf-8
import copy
a = [1,2,3,['a','b','c']]
#浅拷贝拷贝的是外层即顶级对象,对于内层只拷贝引用
#所以在a的外层增加了元素,而c并没有变化.而在a的内层增加元素后,c发生了同样的变化.(回顾b=a)
print('*'*50)
print('--- c = copy.copy(a)---')
c = copy.copy(a)
print('a = %s'%a)
print('c = %s'%c)
a.append(4)
print('---外层a增加了元素4---')
print('a = %s'%a)
print('c = %s'%c)
print('---内层增加了元素"d"---')
a[3].append('d')
print('a = %s'%a)
print('c = %s'%c)
#深拷贝会递归的拷贝所有内容,将所有的内容都独自拷贝了一份.
#故而,无论a的外层还是内层发生变化,都不会影响到d.
print('*'*50)
print('--- d = copy.deepcopy(a) ---')
d = copy.deepcopy(a)
print('a = %s'%a)
print('d = %s'%d)
a.append(5)
print('---外层a增加了元素5---')
print('a = %s'%a)
print('d = %s'%d)
print('---内层增加了元素"e"---')
a[3].append('e')
print('a = %s'%a)
print('d = %s'%d)

运行如下:

**************************************************
--- c = copy.copy(a)---
a = [1, 2, 3, ['a', 'b', 'c']]
c = [1, 2, 3, ['a', 'b', 'c']]
---外层a增加了元素4---
a = [1, 2, 3, ['a', 'b', 'c'], 4]
c = [1, 2, 3, ['a', 'b', 'c']]
---内层增加了元素"d"---
a = [1, 2, 3, ['a', 'b', 'c', 'd'], 4]
c = [1, 2, 3, ['a', 'b', 'c', 'd']]
**************************************************
--- d = copy.deepcopy(a) ---
a = [1, 2, 3, ['a', 'b', 'c', 'd'], 4]
d = [1, 2, 3, ['a', 'b', 'c', 'd'], 4]
---外层a增加了元素5---
a = [1, 2, 3, ['a', 'b', 'c', 'd'], 4, 5]
d = [1, 2, 3, ['a', 'b', 'c', 'd'], 4]
---内层增加了元素"e"---
a = [1, 2, 3, ['a', 'b', 'c', 'd', 'e'], 4, 5]
d = [1, 2, 3, ['a', 'b', 'c', 'd'], 4]

4、拷贝的警告

第一:非容器类型(比如数字,字符串和其他原子类型的对象,例如代码,类型和xrange对象等)没有拷贝一说,浅拷贝是完全用切片操作来完成的。

第二:如果元组变量只包含原子类型对象,那么深拷贝将不会进行。

#coding=utf-8
import copy
a = (1,2,3)
print('*'*50)
print('--- c = copy.copy(a)---')
c = copy.copy(a)
print(a,id(a))
print(c,id(c))
print('*'*50)
print('--- d = copy.deepcopy(a) ---')
d = copy.deepcopy(a)
print(a,id(a))
print(d,id(c))

运行如下:

**************************************************
--- c = copy.copy(a)---
(1, 2, 3) 140394676674992
(1, 2, 3) 140394676674992
**************************************************
--- d = copy.deepcopy(a) ---
(1, 2, 3) 140394676674992
(1, 2, 3) 140394676674992

可见:

对于可变类型来说,深拷贝和浅拷贝是不同的.

而对于不可变类型来说,深拷贝和浅拷贝的结果相同!

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
python模块之time模块(实例讲解)
Sep 13 Python
python绘制铅球的运行轨迹代码分享
Nov 14 Python
Python3读取Excel数据存入MySQL的方法
May 04 Python
python文件选择对话框的操作方法
Jun 27 Python
python 字符串追加实例
Jul 20 Python
Python Opencv提取图片中某种颜色组成的图形的方法
Sep 19 Python
Django实现whoosh搜索引擎使用jieba分词
Apr 08 Python
python实现与redis交互操作详解
Apr 21 Python
python函数中将变量名转换成字符串实例
May 11 Python
快速解释如何使用pandas的inplace参数的使用
Jul 23 Python
Python实现迪杰斯特拉算法并生成最短路径的示例代码
Dec 01 Python
python 如何把docker-compose.yaml导入到数据库相关条目里
Jan 15 Python
Python3中函数参数传递方式实例详解
May 05 #Python
python制作填词游戏步骤详解
May 05 #Python
python开发游戏的前期准备
May 05 #Python
Python实现多态、协议和鸭子类型的代码详解
May 05 #Python
用uWSGI和Nginx部署Flask项目的方法示例
May 05 #Python
基于python实现高速视频传输程序
May 05 #Python
Python远程视频监控程序的实例代码
May 05 #Python
You might like
PHP的一个完整SMTP类(解决邮件服务器需要验证时的问题)
2006/10/09 PHP
ThinkPHP3.1新特性之多层MVC的支持
2014/06/19 PHP
php判断访问IP的方法
2015/06/19 PHP
PHP常见数组排序方法小结
2018/08/20 PHP
php反序列化长度变化尾部字符串逃逸(0CTF-2016-piapiapia)
2020/02/15 PHP
PHP中abstract(抽象)、final(最终)和static(静态)原理与用法详解
2020/06/05 PHP
javascript 正则替换 replace(regExp, function)用法
2010/05/22 Javascript
JavaScript创建对象的写法
2013/08/29 Javascript
jquery实现鼠标滑过小图时显示大图的方法
2015/01/14 Javascript
JS烟花背景效果实现方法
2015/03/03 Javascript
基于JavaScript FileReader上传图片显示本地链接
2016/05/27 Javascript
js 获取站点应用名的简单实例
2016/08/18 Javascript
Javascript 动态改变imput type属性
2016/11/01 Javascript
jQuery通过改变input的type属性实现密码显示隐藏切换功能
2017/02/08 Javascript
vue 中自定义指令改变data中的值
2017/06/02 Javascript
手把手教你把nodejs部署到linux上跑出hello world
2017/06/19 NodeJs
在微信小程序中保存网络图片
2019/02/12 Javascript
微信小程序设置滚动条过程详解
2019/07/25 Javascript
Vue打包后访问静态资源路径问题
2019/11/08 Javascript
vue3.0自定义指令(drectives)知识点总结
2020/12/27 Vue.js
python获得linux下所有挂载点(mount points)的方法
2015/04/29 Python
Python实现对百度云的文件上传(实例讲解)
2017/10/21 Python
python 简单搭建阻塞式单进程,多进程,多线程服务的实例
2017/11/01 Python
python使用tensorflow保存、加载和使用模型的方法
2018/01/31 Python
Django多进程滚动日志问题解决方案
2019/12/17 Python
python 判断txt每行内容中是否包含子串并重新写入保存的实例
2020/03/12 Python
python二维图制作的实例代码
2020/12/03 Python
Python爬取你好李焕英豆瓣短评生成词云的示例代码
2021/02/24 Python
璀璨的珍珠、密钉和个性化珠宝:Lily & Roo
2021/01/21 全球购物
销售演讲稿范文
2014/01/08 职场文书
《小熊住山洞》教学反思
2014/02/21 职场文书
2014学习优秀共产党员先进事迹材料思想汇报
2014/09/14 职场文书
英文自荐信范文
2015/03/25 职场文书
劳动仲裁代理词范文
2015/05/25 职场文书
创业计划书之小型广告公司
2019/10/22 职场文书
Java并发编程之详解CyclicBarrier线程同步
2021/06/23 Java/Android