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 常用 PEP8 编码规范详解
Jan 22 Python
python简单线程和协程学习心得(分享)
Jun 14 Python
python字典操作实例详解
Nov 16 Python
python实现闹钟定时播放音乐功能
Jan 25 Python
python实现QQ邮箱/163邮箱的邮件发送
Jan 22 Python
pandas DataFrame行或列的删除方法的实现示例
Aug 02 Python
Python实现把类当做字典来访问
Dec 16 Python
Python3 xml.etree.ElementTree支持的XPath语法详解
Mar 06 Python
Python数据结构dict常用操作代码实例
Mar 12 Python
Python中使用filter过滤列表的一个小技巧分享
May 02 Python
python属于解释型语言么
Jun 15 Python
利用python进行文件操作
Dec 04 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
手把手教你使用DedeCms V3的在线采集图文教程
2007/04/03 PHP
php addslashes及其他清除空格的方法是不安全的
2012/01/25 PHP
php echo, print, print_r, sprintf, var_dump, var_expor的使用区别
2013/06/20 PHP
php实现的Timer页面运行时间监测类
2014/09/24 PHP
PHP函数func_num_args用法实例分析
2015/12/07 PHP
基于PHP制作验证码
2016/10/12 PHP
php把时间戳转换成多少时间之前函数的实例
2016/11/16 PHP
thinkPHP3.2使用RBAC实现权限管理的实现
2019/08/27 PHP
javascript 拖放效果实现代码
2010/01/22 Javascript
javascript实现捕捉键盘上按下的键
2015/05/05 Javascript
window.location.hash知识汇总
2015/11/09 Javascript
JQuery实现图片轮播效果
2017/05/08 jQuery
AngularJS 实现点击按钮获取验证码功能实例代码
2017/07/13 Javascript
switchery按钮的使用方法
2017/12/18 Javascript
Node.js Buffer用法解读
2018/05/18 Javascript
jQuery实现验证用户登录
2019/12/10 jQuery
JS将指定的某个字符全部转换为其他字符实例代码
2020/10/13 Javascript
gearman的安装启动及python API使用实例
2014/07/08 Python
Python设计模式编程中Adapter适配器模式的使用实例
2016/03/02 Python
python实现八大排序算法(2)
2017/09/14 Python
django小技巧之html模板中调用对象属性或对象的方法
2018/11/30 Python
Django+Xadmin构建项目的方法步骤
2019/03/06 Python
python sklearn常用分类算法模型的调用
2019/10/16 Python
pygame实现烟雨蒙蒙下彩虹雨
2019/11/11 Python
pytorch-神经网络拟合曲线实例
2020/01/15 Python
keras K.function获取某层的输出操作
2020/06/29 Python
python list的index()和find()的实现
2020/11/16 Python
css3加js做一个简单的3D行星运转效果实例代码
2017/01/18 HTML / CSS
计算机通信专业推荐信
2014/02/22 职场文书
厂办主管岗位职责范本
2014/02/28 职场文书
2014最新房贷收入证明范本
2014/09/12 职场文书
2014年高中生自我评价范文
2014/09/26 职场文书
高中校园广播稿3篇
2014/09/29 职场文书
青年人初次创业的“五不要”
2019/08/23 职场文书
导游词之镇江-金山寺
2019/10/14 职场文书
Python中快速掌握Data Frame的常用操作
2021/03/31 Python