Python 中的浅拷贝(copy)和深拷贝(deepcopy)
Contents
- 直接赋值:即对象的引用,其对象的
id
不变。 - 浅拷贝(copy):拷贝父对象,不会拷贝对象的内部的子对象。
- 深拷贝(deepcopy):拷贝父对象及其子对象。
Python 中的
id()
函数用于返回对象的内存地址。
1.直接赋值
直接赋值,即赋值引用,两个变量指向同一对象(同一内存地址)。如下所示:
|
|
可以看到,一开始a
和b
的id
相同,它们指向同一内存地址。现在令a[0] = 11
,那么b
的内容也被同时改变,改变b[1] = 22
,同样的a
的内容也被同时改变,最后它们的id
仍是相同的,再次说明它们的内存地址相同,即指向同一内存地址。
2.浅拷贝
浅拷贝只会拷贝父对象,不会拷贝对象的内部的子对象。如下所示:
|
|
因为c
浅拷贝了a
,所以新增了一个内存地址用于存放c
,它们的id
不同。改变其c
中某个元素的值,a
也没有发生相应的改变,这就是因为内存地址不同了。
对于父对象和子对象,例如在
a = [1, 2, [3, 4]]
中,我们把a[0]
、a[1]
、a[2]
叫做父对象,把a[2][0]
、a[2][1]
叫做子对象。
但是看下面的例子,如下所示:
|
|
一开始d
拷贝了a
,因为新增了一个内存地址用于存放d
,所以id
不同了,内存地址也就不同了。这时候改变a[0]
这一父对象,相应的d[0]
没有改变,说明父对象的内存地址发生改变了,id
也不一样了;而改变子对象a[2][0]
元素,相应的d[2][0]
元素被改变了,说明子对象的内存地址不变,id
是相同的。
所以说:浅拷贝会拷贝父对象,不会拷贝子对象。
3.深拷贝
在使用深拷贝之前,需要导入
copy
模块,即import copy
。
深拷贝完全拷贝了父对象及子对象。如下所示:
|
|
这里e
深拷贝了a
,改变a
中某个元素的值,e
中的元素不会发生相应的改变,说明a
和e
的id
不同,内存地址也就不同。
4.总结
- Python 中对象的赋值都是进行对象引用(内存地址)的传递。
- 浅拷贝它拷贝了对象,但对于对象中的元素,依然使用的是原始的引用(内存地址),但所含元素(父对象)的子元素(子对象)不会被拷贝。
- 深拷贝可将父对象和子对象进行拷贝。