博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python深拷贝与浅拷贝
阅读量:5859 次
发布时间:2019-06-19

本文共 1267 字,大约阅读时间需要 4 分钟。

python深拷贝与浅拷贝

可变对象与不可变对象

要理解深拷贝和浅拷贝,首先要理解可变对象和不可变对象。

不可变对象:该对象所指向的内存中的值不能被改变,修改对象的值时,由于其指向的值不能被改变,因此实际上是在内存中重新开辟一个地址用来存储新的值,然后将对象指向这个新值。本质上是两个对象,赋值前后对象id发生了变化。python中的不可变对象包括:bool、int、str、float、tuple、frozenset、None。

可变对象:该对象所指向的内存中的值可以被改变。变量(引用)的值发生改变时,实际上是其指向的值直接发生改变,没有开辟新的内存地址。python中的可变对象包括:list、dict、set。

 python中的赋值语句不会创建对象的拷贝,仅仅只是将变量名称绑定到一个对象上。对于不可变对象,这种操作不会产生差别,但是处理可变对象或可变对象的集合时,你可能希望创建这些对象的“真实拷贝”,在修改创建的拷贝时不改变原始的对象。

浅拷贝:通常指构造一个新的集合对象,然后用原始对象中的找到的子对象的引用来填充它。浅层的复制只有一层深度,复制过程中不会递归,所以不会创建子对象本身的副本。

深拷贝:深拷贝使复制过程递归,即首先构造一个新的集合对象,然后递归地用在原始对象中找到的子对象的副本来填充它。通过深拷贝复制对象,是原始对象及其所有子对象的完全独立的克隆。

赋值与引用

python的赋值语句不会复制对象,而是创建一个对象的引用(可以理解为标签)。代码示例:

上图示例中,创建了两个变量(实际两个变量表示的是同一个列表),但两个变量id相同,指向的是同一个内存地址。

创建浅拷贝

仍以python列表为例,通常我们会用list()函数来复制一个列表,这个复制过程,就是一个浅拷贝。代码示例:

可以看到,通过浅拷贝方式,确实是复制了一个列表。复制前后两个变量的id不同,两个变量指向两个不同的内存地址,且修改其中一个列表中的值,对另一个列表不会产生影响。

而之所以称这种复制方式为浅拷贝,是因为这种拷贝只对一层对象有效,当列表中有子对象时,对子对象的修改将同时影响原始对象和拷贝对象。代码示例:

如上图所示,修改第一层次的成员值,不会影响拷贝对象;修改子对象的成员值(第二层次),会同时影响原始对象和拷贝对象。这是因为浅拷贝没有递归复制原始对象的值,只复制了第一层,因此拷贝对象中复制了子对象的引用,并没有复制子对象的值。

创建深拷贝

python标准库中的copy模块提供了创建python对象的浅拷贝和深拷贝的接口。使用deepcopy()函数,可以创建一个对象的深拷贝。代码示例:

如上图所示,通过深拷贝复制的对象递归克隆了原始对象,两者是完全独立的。无论怎样修改其中一个对象,都不会对另一个对象产生影响。

总结

  • 不可变对象没有深拷贝和浅拷贝之分,可以理解为都是深拷贝
  • 创建对象的浅拷贝不会克隆子对象,不能完全对立与原始对象
  • 深拷贝会递归克隆原始对象,两者完全独立,互不影响,创建深拷贝的速度较慢
原文地址

转载地址:http://vbgjx.baihongyu.com/

你可能感兴趣的文章
在IT界取得成功应该知道的10件事
查看>>
我的友情链接
查看>>
电子商务站点遭勒索 F5路见不平显神功
查看>>
Zabbix | 使用odbc方式监控MySQL
查看>>
MongoDB_3.2.10 集群 - 副本集
查看>>
合肥市地方税务局异地容灾系统项目<45万,RORKE,EMC,NETAPP
查看>>
TermServDevices 错误解决方案
查看>>
[总结]FFMPEG视音频编解码零基础学习方法
查看>>
oracle sqlloader 控制文件示例和cmd导入命令
查看>>
SecureCRT自动记录日志
查看>>
文档:Windows Server 2012 虚拟光纤通道(HBA)
查看>>
继续配置postfix记录
查看>>
社会化评论插件之友言
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
ssl协议工作原理
查看>>
水仙花代码
查看>>
XenDesktop 5 MCS Pool/池类型桌面重启/注销即还原
查看>>
vsftpd 配置:chroot_local_user与chroot_list_enable详解
查看>>
solidworks中 toolbox调用出现未配置的解决方法
查看>>