Python中的浅拷贝与深拷贝

六开彩预测内部

Python中的浅拷贝与深拷贝

(点击上方公众号,可快速关注一起学Python)

六开彩预测内部在 Python 中,通过一个对象向另外一个对象赋值,实际仅仅是赋值了对象的引用,而非创建一个对象并赋值。那如何真正拷贝对象呢?我们看一下两种不同的拷贝方式。

先从一个示例看起:

Anndy = ["Anndy", ["age", 24]]Tom = Anndy[:]Cindy = list(Anndy)>>> id(Anndy)>>> id(Tom)>>> id(Cindy)

运行结果如下:

35574048

35575408

8815920

由此可见,是创建了三个不同的对象。但是事实真的是这样吗?让我们修改一下名字和年龄看看:

Tom[0] = "Tom"Cindy[0] = "Cindy"print Anndy, Tom, Cindy

运行结果如下:

["Anndy", ["age", 24]] ["Tom", ["age", 24]] ["Cindy", ["age", 24]]

修改年龄没有任何问题。我们再来修改一下Tom的年龄,修改为12岁:

Tom[1][1] = 12print Anndy, Tom, Cindy

运行结果如下:

["Anndy", ["age", 12]] ["Tom", ["age", 12]] ["Cindy", ["age", 12]]

哇喔,所有人的年龄都被修改了。这真是恐怖啊,并不是我们想要的结果。为啥会是这样呢?我们可以打印一下列表中各个对象的ID看一下:

print [id(x) for x in Anndy]print [id(x) for x in Tom]print [id(x) for x in Cindy]

运行结果如下:

[6003744, 35336880]

[35426032, 35336880]

[35365376, 35336880]

由此可见,第二个列表的元素是相同的。这是为什么呢?

原因就是浅拷贝。

构造方法或切片 [:] 做的是浅拷贝(即拷贝了最外层容器,副本中的元素是原容器中元素的引用)。如果所有元素都是不可变的(比如名字字符串,修改的时候会重新创建对象,仅仅包括原子对象的元组也属于这种情况),那么这样没有问题,还能节省内存。但是,如果有可变的元素,可能就会导致意想不到的问题,正如刚刚,修改一个人的年龄,所有人的年龄都发生了变化。

那么现在来看一下深拷贝。深拷贝,顾名思义,深层次的拷贝,不仅仅拷贝最外层容器,还会拷贝容器中的元素。这是利用copy中的deepcopy方法来实现的。

实现如下:

import copyAnndy = ["Anndy", ["age", 24]]Tom = copy.deepcopy(Anndy)Cindy = copy.deepcopy(Anndy)Tom[0] = "Tom"Cindy[0] = "Cindy"Tom[1][1] = 12print Anndy, Tom, Cindyprint [id(x) for x in Anndy]print [id(x) for x in Tom]print [id(x) for x in Cindy]

运行结果如下:

["Anndy", ["age", 24]] ["Tom", ["age", 12]] ["Cindy", ["age", 24]]

[34970656, 35511712]

[35570608, 35541360]

[35496448, 35541440]

OK,仅仅是Tom的年龄被修改了。另外,还是需要注意一下,对于不可变的对象,比如字符串,比如包括原子对象的元组,对其深拷贝不会进行

浅拷贝与深拷贝的原理你深入理解了吗?

深入阅读 :

Python内存管理机制

看完本文有收获?请转发分享给更多人

关注「Python那些事」,提升Python技能

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。

我要收藏
赞一个
踩一下
分享到
相关推荐
精选文章

分享
评论
六开彩预测内部
天线宝宝六肖 今天香港马报资料 手机报码最新开奖 六开彩预测内部 平特三连肖网址 香港现场开奖报码 香港六合特码图库 看图解平特一肖 香港本港台现场报码 香港本港台现场报码