初探python对象复制问题的深拷贝和浅拷贝

时间:2022-01-31 21:30:07

前阶段学习python时遇到对象拷贝的问题,感觉有个不小的坑,于是乎搜了一下网上相关博客的介绍,然而总觉得叙述太长,不够简洁。本文通过总结前人经验,并根据自己的理解,简单谈一谈python中的拷贝小坑。
python中实现对象复制的方法大致有3种:简单粗暴直接‘=’赋值、浅拷贝和深拷贝,下面我们一一来看:
首先是直接赋值。先来看一个例子:

>>> n0 = [0,1,2,[30,31,[320,321]]]
>>> n1 = n0
>>> n0[1] = 11
>>> n1
[0, 11, 2, [30, 31, [320, 321]]]
>>> n0[3][1] = 3111
>>> n1
[0, 11, 2, [30, 3111, [320, 321]]]

从这个例子可以看出,赋值就是原对象变成啥我就变成啥。打个比方,今天上课讲了python,aa上课记了笔记,hh生病旷课。但是hh知道aa记了笔记,想要查看只需要去找aa借笔记就行了,如果aa修改了笔记内容,那么hh去借就只能看到修改后的笔记内容。赋值就是借笔记的一个过程
然后是浅拷贝copy()。我们继续看一个例子:

>>> import copy
>>> n0 = [0,1,2,[30,31,[320,321]]]
>>> n2 = copy.copy(n0)
>>> n0[0] = 100
>>> n0[3][0] = 333333
>>> n0
[100, 1, 2, [333333, 31, [320, 321]]]
>>> n2
[0, 1, 2, [333333, 31, [320, 321]]]

从这个例子可以看出,浅拷贝就是复制浅层信息(啥?这不等于没说吗!别着急,接着看。)我们再来打个比方:还是上课,还是aa记了笔记,hh旷课了,这次hh把aa笔记的大纲抄了下来,如果需要查看内容,再根据大纲查询相关部分的笔记,如果aa修改了笔记大纲,那么hh是知道的,因为他之前抄了大纲,但是如果aa修改了某一条大纲下的笔记内容,那么hh就不知道了,他还是根据之前摘抄的大纲寻找对应的笔记,找到的也是修改过后的你笔记内容了。浅拷贝就是摘抄大纲的过程
最后是深拷贝deepcopy。我们接着来看一个例子:

>>> n0 = [0,1,2,[30,31,[320,321]]]
>>> n3 = copy.deepcopy(n0)
>>> n0[0] = 10000
>>> n0[3][2][0] = 666
>>> n0
[10000, 1, 2, [30, 31, [666, 321]]]
>>> n3
[0, 1, 2, [30, 31, [320, 321]]]

从上面的例子可以看出来,无论深拷贝前的对象怎么变化,拷贝后的对象始终都是最初的模样。我们继续之前的比方,在经历了之前的教训,hh为了防止aa篡改笔记内容,hh将笔记所有内容全部摘抄了一遍,连标点符号都没放过,这样无论aa之后再怎么修改笔记,hh都能知道。深拷贝就是摘抄笔记全部内容的过程
现在我们来总结一下:赋值——知道哪里有一份笔记;浅拷贝——知道哪里有一份笔记并且摘抄了笔记的大纲;深拷贝——将笔记全部摘抄一遍。