【个人笔记】Python - 深拷贝与浅拷贝的区别
1>浅拷贝
浅拷贝是copy模块里面的copy方法实现
浅拷贝后,改变原始对象中为可变类型的元素的值,会同时影响拷贝对象;改变原始对象中为不可变类型的元素的值,不会响拷贝对象。
# 导入copy模块 import copy list1 = [[1, 2], 3, 4, 5, ] list2 = copy.copy(list1) # 查看两个对象的地址,可一看到地址不一样 print(id(list1)) print(id(list2))
可以看到输出结果,证明两个对象地址是不一样的
这时我们尝试改变原始对象list1
# 导入copy模块 import copy list1 = [[1, 2], 3, 4, 5] list2 = copy.copy(list1) # 查看两个对象的地址,可一看到地址不一样 print(id(list1)) print(id(list2)) # 第一个元素地址是否相同? print(id(list1[0])) print(id(list2[0])) # 改变list1的第一个元素的值,查看list2是是否变变化 list1[0][1] = 7 # 神奇的事情发生了,list2也改变了,但是我们没有对list2进行操作呀! print(list2) # 向list1增加元素 list1.append(3) print(list1) print(list2)
看一下输出结果:
因此我们可以得到以下结论:
list2是list1进行浅拷贝(copy)生成的对象,可以看到list1和list2两个对象整体的id是不同的
但是里面的第1个元素列表的地址却是相同的(指向同一个地址)
所以list1在相同地址改变元素值时,list2也会改变
这里在向list1末尾追加元素时,浅拷贝对象没有被追加,是因为在浅拷贝后操作的。
2>深拷贝
深拷贝copy模块里面的deepcopy方法实现
经过深拷贝后,原始对象和拷贝对象所有的可变元素地址都没有相同的了
# 导入copy模块 import copy list1 = [[1, 2], 3, 4, 5] list3 = copy.deepcopy(list1) # 查看两个对象的地址,可一看到地址不一样 print(id(list1)) print(id(list3)) # 第一个元素地址是否相同? print(id(list1[0])) print(id(list3[0])) # 改变list1的第一个元素的值,查看list3是是否变变化 list1[0][1] = 7 # 可以看到list3没有变化 print(list3) # 向list1增加元素 list1.append(3) print(list1) print(list3)
输出结果:
因此我们可以得到以下结论:
经过深拷贝(deepcopy)过后,拷贝对象和源对象所有元素地址都不一样,因此无论源对象怎么改变,拷贝对象都不会变
总之: 浅拷贝就是藕断丝连,还存在联系
深拷贝就是一刀斩断,莫得关系了