深拷贝和浅拷贝是python必须要掌握的内容,无论你是面试开发、测试、运维等职位,只要是python,深拷贝与浅拷贝是面试官常问的一个重要知识点。
(关注“测试开发自动化” 弓中皓,获取更多学习内容)
一、 深浅拷贝异同
相同点:
无论深拷贝还是浅拷贝都会创建一个新对象。即:拷贝出来的对象的id不同。
不同点:
浅拷贝:只拷贝了对象,对象内的元素并不会发生拷贝。
深拷贝:不仅拷贝对象,对象内的元素也会发生拷贝。
二、浅拷贝
2.1 浅拷贝举例
来看一个浅拷贝的例子:
import copy a = [1, 2, [3, 4]] b = copy.copy(a) # 浅拷贝 print(id(a)) # 输出结果:2401212115720 print(id(b)) # 输出结果:2401212116104 print(id(a[2])) # 输出结果:1508928560 print(id(b[2])) # 输出结果:1508928560
代码解释:
1)b通过浅拷贝a之后,a和b对象的id不同(与相同点吻合)
2)分别取a和b的第3个元素的id(第3个元素是可变对象),发现a和b的第3个元素的id值相同。说明并没有拷贝元素的id,也就是说a和b内部的元素id都是相同的。(与浅拷贝的不同点吻合)
2.2 浅拷贝修改元素值
上面说到了对象a和b内部的元素id都是相同的,那就意味着a、b对象内部的元素是同一个东西。
★重点★:但是并不代表浅拷贝下修改了a内元素元素的值,b元素内元素的值一定会发生变化,还要看被修改的值是否是可变对象:
【情况一】:如果是修改的元素是可变对象,那么修改了a内元素,b内元素会发生变化,该元素的在a、b内的id不会发生变化;
【情况二】:如果修改的元素是不可变对象,那么修改了a内元素,b内元素不会发生变化,该元素在a、b内的id会发生变化
# 情况1举例:修改的元素是可变对象 import copy a = [1, 2, [3, 4]] b = copy.copy(a) # 浅拷贝 a[2][1] = 4 # 修改a中[3, 4]元素,将3修改为4 print(a) # 打印结果:[1, 2, [3, 4]] print(b) # 打印结果:[1, 2, [3, 4]] print(id(a[2])) # 打印结果:2561215900424 print(id(b[2])) # 打印结果:2561215900424
代码解释:
a的元素[3, 4]是可变对象,所以修改了a元素,b元素也会同步修改,但是由于是浅拷贝,a、b内元素的id并不会发生变化。
# 情况2举例:修改的元素是不可变对象 import copy a = [1, 2, [3, 4]] b = copy.copy(a) # 浅拷贝 a[1] = 4 # 修改a中第1个位置上的元素,即将2修改为4 print(a) # 打印结果:[1, 4, [3, 4]] print(b) # 打印结果:[1, 2, [3, 4]] print(id(a[1])) # 打印结果:1508928624 print(id(b[1])) # 打印结果:1508928560
代码解释:
a元素的第一个元素是数值型(int类型),是不可变对象,所以修改了a元素,b并不会发生变化,a与b在第一个位置上的元素就属于两个不同的东西了,自然a、b的id就不相等。
三、深拷贝
3.1 深拷贝举例
import copy a = [1, 2, [3, 4]] b = copy.deepcopy(a) # 深拷贝 print(id(a)) # 输出结果:2034433010824 print(id(b)) # 输出结果:2034433010248 print(id(a[2])) # 输出结果:2463430159112 print(id(b[2])) # 输出结果:2463430154184
代码解释:
1)b通过浅拷贝a之后,a和b对象的id不同(与2.1中相同点吻合)
2)分别取a和b的第3个元素的id(第3个元素是可变对象),发现a和b的第3个元素的id值不相同。说明a拷贝了元素b,也就是说a和b内部的元素id都是不同的个体。(与深拷贝的不同点吻合)
3.2 深拷贝修改值
与浅拷贝相反,可以将深拷贝也分为两种情况:
【情况一】:如果是修改的元素是可变对象,那么修改了a内元素,b内元素不会发生变化,该元素的在a、b内的id会发生变化;
【情况二】:如果修改的元素是不可变对象,那么修改了a内元素,b内元素不会发生变化,该元素在a、b内的id会发生变化(与浅拷贝相同)
# 情况1举例:修改的元素是可变对象 import copy a = [1, 2, [3, 4]] b = copy.deepcopy(a) # 深拷贝 a[2][0] = 4 # 修改a中[3, 4]元素,将3修改为4 print(a) # 打印结果:[1, 2, [4, 4]] print(b) # 打印结果:[1, 2, [3, 4]] print(id(a[2])) # 打印结果:1975929744136 print(id(b[2])) # 打印结果:1975929739208
代码解释:
a的元素[3, 4]是可变对象,是深拷贝,所以修改了a元素,b元素并不会同步修改。由于是深拷贝,修改a内可变对象元素,b内元素的id并不会发生变化。
欢迎点赞+关注+收藏
(关注“测试开发自动化” 弓中皓,获取更多学习内容)