深拷贝
如何实现深拷贝
通过调用标准库模块copy中的函数deepcopy()实现
什么是深拷贝
所谓深拷贝,指的是:对于某个对象,创建与该对象具有相同值的另一个对象,同时,这两个对象内部嵌套的对应可变子对象全都不是同一个对象。简单来说,外部和内部都进行了拷贝。
验证
-
列表对象中嵌套列表对象和整数对象
L1 = [[3, 6], 8] L2 = copy.deepcopy(L1) print(L2) #[[3, 6], 8] print('id(L1):%s' % id(L1)) #id(L1):140690863572936 print('id(L2):%s' % id(L2)) #id(L2):140690863552456 print('id(L1[0]):%s' % id(L1[0])) #id(L1[0]):140690863458312 print('id(L2[0]):%s' % id(L2[0])) #id(L2[0]):140690931192072 print('id(L1[1]):%s' % id(L1[1])) #id(L1[1]):10914720 print('id(L2[1]):%s' % id(L2[1])) #id(L2[1]):10914720 L1[0][1] = 7 L1[1] = 9 print(L1) #[[3, 7], 9] print(L2) #[[3, 6], 8]
结论
对于深拷贝而言,对象内部嵌套的可变子对象全都不是同一个对象。如下图所示:
修改L1嵌套对象前:
修改L1嵌套对象后:
不可变对象内部嵌套可变对象会进行深拷贝吗?
验证
-
创建元组对象并嵌套列表对象和整数对象
t1 = ([3, 6], 8) t2 = copy.deepcopy(t1) print(t2) #([3, 6], 8) print('id(t1):%s' % id(t1)) #id(t1):140690887223176 print('id(t2):%s' % id(t2)) #id(t2):140690863551752 print('id(t1[0]):%s' % id(t1[0])) #id(t1[0]):140690863537800 print('id(t2[0]):%s' % id(t2[0])) #id(t2[0]):140690863482888 print('id(t1[1]):%s' % id(t1[1])) #id(t1[1]):10914720 print('id(t2[1]):%s' % id(t2[1])) #id(t2[1]):10914720
结论
如果不可变对象内部又嵌套了可变子对象,那么在深拷贝之后,会创建一个与该不可变对象具有相同值的另一个对象。
深拷贝和浅拷贝的一个共同点
同样的,对于没有嵌套子对象的不可变对象,例如:整数对象、字符串对象和元组对象等,不会进行拷贝,也就是说不会创建另一个对象。
验证
-
创建整数对象,并验证
i = 18 ic1 = copy.deepcopy(i) print(ic1) #18 print('id(i): %s' % id(i)) # id(i): 10915040 print('id(ic1): %s' % id(ic1)) # id(ic1): 10915040
内部嵌套只有整数对象时,通过id查看内存地址可以发现,deepcopy深拷贝同样也不会创建一个新对象
-
创建元组对象,并验证
t = (1, 2, 3) tc = copy.deepcopy(t) # (1, 2, 3) print(tc) print('id(t):%s' % id(t)) #id(t):140690863541128 print('id(tc):%s' % id(tc)) #id(tc):140690863541128
内部嵌套只有元组对象时,通过id查看内存地址可以发现,deepcopy深拷贝同样也不会创建一个新对象