深浅拷贝
参考:https://www.cnblogs.com/echoboy/p/9059183.html
https://blog.csdn.net/xmp1669217327/article/details/81046519
一.变量存储
在了解深浅拷贝之前,我们简单了解一下python中可变和不可变类型的存储过程。
1.可变类型的存储:新建一个可变类型如列表(内部存储的都是地址),如果在列表本身修改(增、删、改),列表本身的地址不发生改变,因为不会新开辟内存空间。
2.不可变类型的存储:每新建一个变量,都会开辟一个新的地址。
v = [4,5]
lsts = [1,2,3,v]
v = [4,5]
lsts = [1,2,3,v]
v = 10 #v重新赋值,重新开辟一个新的地址空间,重新指向
v = [4,5]
lsts = [1,2,3,v]
v.append(10) #在v的基础上添加,地址不会改变
无论是直接赋值、浅拷贝还是深拷贝,都是内存地址的复制。在下面,a代表原对象,b代表拷贝成功的对象。
二.直接赋值(=)
其实就是拷贝对象的引用。
----------------------
a=[1,2,3,[4,5]]
b=a
#a[0]=10
#print(a) [10,2,3,[4,5]]
#print(b) [10,2,3,[4,5]]
#a[3][0]=10
#print(a) [1,2,3,[10,5]]
#print(b) [1,2,3,[10,5]]
#b[0]=10
#print(a) [10,2,3,[4,5]]
#print(b) [10,2,3,[4,5]]
#b[3][0]=10
#print(a) [10,2,3,[4,5]]
#print(b) [10,2,3,[4,5]]
由上可知,无论是不可变数据,还是可变数据,源对象a改变,则b也改变;拷贝对象b改变,相应的是a也改变,因为两者的内存、值都一样
三.浅拷贝
首先需要了解拷贝的本质:就是复制一个新的东西,且复制前后数据互不影响(要想互不影响,就需要新建内存存储)。浅拷贝就是不完全拷贝,只拷贝父对象(新建内存用来存父对象),同时拷贝子对象的引用,此处注意'引用',只是指向子对象,而非新建内存存储子对象,因此被拷贝的子对象的改变必定会导致新拷贝的改变(不可变类型不变,可变类型变,新建子对象也互不影响)
拷贝最外层对象,父级对象
----------------------------
不可变数据:a改变,不影响b;b改变,不影响a,因为两者互不影响。
可变数据:a改变,b也改变;b改变,a也改变,因为两者指向相同
四.深拷贝
完全拷贝所有对象,父级对象和子级对象,拷贝父对象的同时递归拷贝子对象
-----------------------------
不可变数据:a改变,不影响b;b改变,不影响a,因为两者互不影响。
可变数据:a改变,不影响b;b改变,不影响a,因为两者互不影响。