5 张图彻底理解 Python 中的浅拷贝与深拷贝

举报
竹叶青 发表于 2019/10/28 22:32:30 2019/10/28
【摘要】 假设你去面试 Python 开发岗,面试官如果对基础比较看重的话,那么很可能会问你这样的问题“谈谈你对 Python 中的浅拷贝和深拷贝的理解?”若平时你在开发中过度使用 deepcopy,以至于忘记了浅拷贝(shallow copy)和深拷贝(deep copy)的区别,那很可能要栽大跟头了。本文转载一篇小吉大佬的文章,帮助大家更好的理解深拷贝和浅拷贝的区别。转载来源公众号:鸡仔说“ 阅读...

假设你去面试 Python 开发岗,面试官如果对基础比较看重的话,那么很可能会问你这样的问题

“谈谈你对 Python 中的浅拷贝和深拷贝的理解?”

若平时你在开发中过度使用 deepcopy,以至于忘记了浅拷贝(shallow copy)和深拷贝(deep copy)的区别,那很可能要栽大跟头了。

本文转载一篇小吉大佬的文章,帮助大家更好的理解深拷贝和浅拷贝的区别。



转载来源

公众号:鸡仔说

 

阅读本文大概需要 7 分钟。

 



建议在读这篇文章之前,看下原作者之前写的文章《你真的理解Python中的赋值、传参吗?》,它有助于你更快的理解本文


Python 的引用计数

首先我们要知道,Python 内不可变对象的内存管理方式是引用计数。因此,我们在谈论拷贝时,其实谈论的主要特点都是基于可变对象的。我们来看下面这段代码


640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1


输出如下


640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1

因为我们这里操作的是不可变对象,Python 用引用计数的方式管理它们,所以 Python 不会对值相同的不可变对象,申请单独的内存空间。只会记录它的引用次数


浅拷贝

我们先来比较一下浅拷贝和赋值在可变对象上的区别


640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1

输出结果

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1

发现没有,赋值就是对物体进行贴标签操作,作用于同一物体。而浅拷贝则会创建一个新的对象,至于对象中的元素,它依然会引用原来的物体,我们再来看一段例子


640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1

输出如下

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1


640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1


操作不可变对象时,由于引用计数的特性,被拷贝的元素改变时,就相当于撕掉了原来的标签,重新贴上新的标签一样,对于我们已拷贝的元素没有任何影响。因此在操作不可变对象时,浅拷贝和深拷贝是没有区别的


640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1

输出结果

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1

由于浅拷贝会使用原始元素的引用(内存地址)。所以在在操作被拷贝对象内部的可变元素时,其结果是会影响到拷贝对象的


深拷贝

深拷贝遇到可变对象,则又会进行一层对象创建,所以你操作被拷贝对象内部的可变对象,不影响拷贝对象内部的值


640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1

输出如下

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1

总结

因此,在下次我们遇到这类问题时,我们说出以下关键点,基本就很稳了

  1. 由于 Python 内部引用计数的特性,对于不可变对象,浅拷贝和深拷贝的作用是一致的,就相当于复制了一份副本,原对象内部的不可变对象的改变,不会影响到复制对象

  2. 浅拷贝的拷贝。其实是拷贝了原始元素的引用(内存地址),所以当拷贝可变对象时,原对象内可变对象的对应元素的改变,会在复制对象的对应元素上,有所体现

  3. 深拷贝在遇到可变对象时,又在内部做了新建了一个副本。所以,不管它内部的元素如何变化,都不会影响到原来副本的可变对象


参考资料

图解 Python 中赋值、浅拷贝、深拷贝的区别

Python中 copy, deepcopy 的区别及原因

转载声明:本文转载自公众号【进击的Coder】。

原文链接:https://mp.weixin.qq.com/s/HIvGqACmI8nO8FTCu2ECDw

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。