python的浅拷贝和深拷贝
1.浅拷贝只拷贝外层,外层数据改变不影响(改变前后不一样),内层改变影响(改变前后一样)
2.深拷贝都拷贝,外层内层改变都不影响(没有任何关系)
举个例子:
有一份报告,浅拷贝如同在手机上观看(报告更新我们看到的内容也更新)
深拷贝如同把他摘抄在纸上观看(报告更新但我们看到的还是原来的内容)
浅拷贝
浅拷贝是对一个对象父级(外层)的拷贝,并不会拷贝子级(内部)。
使用浅拷贝的时候,分为两种情况:
第一种,如果最外层的数据类型是可变的,比如说列表,字典等,浅拷贝会开启新的地址空间去存放。
第二种,如果最外层的数据类型是不可变的,比如元组,字符串等,浅拷贝对象的时候,还是引用对象的地址空间。
外层可变
a = [1,2]
b = [3,4]
c = [a,b]
d = copy.copy(c)
print(c) # [[1, 2], [3, 4]]
print(d) # [[1, 2], [3, 4]]
print(c is d) # False
print(a is d[0]) # True
print(b is d[1]) # True
c[0].append(5)
print(c) # [[1, 2, 5], [3, 4]]
print(d) # [[1, 2, 5], [3, 4]]
外层不可变
a = [5,6]
b = [7,8]
c = (a,b)
d = copy.copy(c)
print(c) #([5, 6], [7, 8])
print(d) #([5, 6], [7, 8])
print(c is d) # True
print(a is d[0]) # True
print(b is d[1]) # True
c[0].append(9)
print(c) #([5, 6, 9], [7, 8])
print(d) #([5, 6, 9], [7, 8])
以上代码我们可以得出结论:浅拷贝后,原来对象的改变会影响拷贝到的对象
深拷贝
深拷贝对一个对象是所有层次的拷贝(递归),内部和外部都会被拷贝过来。
深拷贝也分两种情况:
第一种,最外层数据类型可变。这个时候,内部和外部的都会拷贝过来。
第二种,外层数据类型不可变,如果里面是可变数据类型,会新开辟地址空间存放。如果内部数据类型不可变,才会如同浅拷贝一样,是对地址的引用。
先看一下简单的深拷贝
a = [9,10]
b = copy.deepcopy(a)
print(b) # [9, 10]
print(a is b) # False
a.append(11)
print(a) # [9, 10, 11]
print(b) # [9, 10]
接下来看嵌套的深拷贝
(1)外层内层都是可变
a = [11,12]
b = [13,14]
c = [a,b]
d = copy.deepcopy(c)
print(d) # [[11, 12], [13, 14]]
print(c is d) # False
print(a is d[0]) # False
print(b is d[1]) # False
c.append(15)
print(c) # [[11, 12], [13, 14], 15]
print(d) # [[11, 12], [13, 14]]
(2)外层不可变,内层可变
a = [15,16]
b = [17,18]
c = (a,b)
d = copy.deepcopy(c)
print(d) # ([15, 16], [17, 18])
print(c is d) # False
print(a is d[0]) # False
print(b is d[1]) # False
c[0].append(19)
print(c) # ([15, 16, 19], [17, 18])
print(d) # ([15, 16], [17, 18])
(3)外层可变,内层不可变
a = (19,20)
b = (21,22)
c = [a,b]
d = copy.deepcopy(c)
print(d) # [(19, 20), (21, 22)]
print(c is d) # False
print(a is d[0]) # True
print(b is d[1]) # True
c.append(15)
print(c) # [(19, 20), (21, 22), 15]
print(d) # [(19, 20), (21, 22)]
(4)外层内层都不可变
a = (23,24)
b = (25,26)
c = (a,b)
d = copy.deepcopy(c)
print(d) # ((23, 24), (25, 26))
print(c is d) # True
print(a is d[0]) # True
print(b is d[1]) # True
结论:
深拷贝就是完全跟以前就没有任何关系了,原来的对象怎么改都不会影响当前对象
浅拷贝,原对象的可变元素改变的话会改变当前对象