Python深拷贝与浅拷贝用法实例分析
作者:xuezhangjun 发布时间:2023-11-06 01:25:04
本文实例讲述了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程序设计有所帮助。
来源:https://blog.csdn.net/xuezhangjun0121/article/details/76945033
猜你喜欢
- 在运维场景下,我们经常需要在服务器上用正则表达式来匹配IP地址。shell和其它编程语言一样,也可以使用正则分组捕获,不过不能使用 $1或\
- 这篇文章主要介绍了Python类如何定义私有变量,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以
- 当我们导入的模型含有自定义层或者自定义函数时,需要使用custom_objects来指定目标层或目标函数。例如:我的一个模型含有自定义层“S
- 最近在为公司做一个门户网站,项目并不咋D,可规划却不小.在做的过程中就发现修改占了很大的工作量.于是就开始想了想如何使前端修改轻松一些.这个
- 本文实例为大家分享了Python/C++实现字符串逆序的具体代码,供大家参考,具体内容如下题目描述:将字符串逆序输出Python实现一:借助
- 什么是MySql数据库?通常意义上,数据库也就是数据的集合,具体到计算机上数据库可以是存储器上一些文件的集合或者一些内存数据的集合。我们通常
- [本站原创]在我们浏览了一些网页时,经常会弹出一些信息窗口或浏览器窗口以显示一些公告内容,想知道这些窗口是怎么制作出来的吗?如果你还不曾知道
- 以下为测试例子。 1.首先创建两张临时表并录入测试数据: 代码如下:create table #temptest1 ( id i
- 如何制作一个搜索引擎链接程序?多收集几个网站的,然后我们引用它到自己的页面中。接下来,我们要创建页面用于搜索:<center>&
- 很多人喜欢把一个网站中相同的部分象是统一的页面logo,版权声明等做成一个过程,然后放到一个include文件中,这样所有的页面就都可以使用
- python——pip install xxx报错SyntaxError: invalid syntax在安装好python后,进入pyth
- 优秀的Stoyan Stefanov在他的新书中(《Javascript Patterns》)介绍了很多编写高质量代码的技巧,比如避免使用全
- 最近项目很忙没机会更新博客。有朋友在和我谈学艺术的就业问题,就随便谈一下自己的想法。每年中国美院报考的人数与日俱增,越来越多的人投入到艺术设
- PyQt5数据拖曳Drag与Drop介绍为用户提供的拖曳功能很直观,在很对桌面应用程序中,复制或移动对象都可以通过拖曳来完成基于MIME类型
- sys.argv[]说白了就是一个从程序外部获取参数的桥梁,这个“外部”很关键,因为我们从外部取得的参数可以是多个,所以获得的是一个列表(l
- 虽然你可以使用一个类似的技术以拒绝过大的文件(通过检查$uploadedfile_size变量),但是通常这不是一个好主意。在得到这个变量之
- 探究多个装饰器执行顺序装饰器是Python用于封装函数或代码的工具,网上可以搜到很多文章可以学习,我在这里要讨论的是多个装饰器执行顺序的一个
- 前段时间做视频时需要演示电脑端的操作,因此要用到屏幕录制,下载了个迅捷屏幕录制,但是没有vip录制的视频有水印且只能录制二分钟,于是鄙人想了
- 复制目录: 包含多层子目录方法: 递归, 深度遍历,广度遍历深度遍历&广度遍历:思路:1.获得源目录子级目录,并设置目标目录的子级路
- def report_hook(count, block_size, total_size):... &n