python--深拷贝和浅拷贝
先上例子
1 def test_fun(): 2 a = [1, "hi", [2, 3], {"key": "123"}] 3 b = copy.copy(a) 4 c = copy.deepcopy(a) 5 print('id(a)=',id(a)) 6 print('id(b)=',id(b)) 7 print('id(c)=', id(c)) 8 a[2].append(4) 9 a[0]=2 10 print('a=',a) 11 print('b=',b) 12 print('c=',c)
运行结果:
id(a)= 1638010289472
id(b)= 1638010288576
id(c)= 1638010289024
a= [2, 'hello', [2, 3, 4], {'key': '123'}]
b= [1, 'hello', [2, 3, 4], {'key': '123'}]
c= [1, 'hello', [2, 3], {'key': '123'}]
总结如下:
浅拷贝:
1.浅拷贝会创建一个新的容器对象
2.对于对象元素,浅拷贝只使用了原始元素的引用
深拷贝:
1.深拷贝会创建一个新的容器对象
2.对于对象的元素,深拷贝会重新生成一个对象
首先,我们看到例子中id(a) id(b) id(c) 为三个不同的值 ,是因为b,c 分别创建了新的容器
其次,a[2]=[2,3] 这个列表元素发生了变化,但是 b[2] 仍然保持和a[2] 相同,c[2] 保持原来的值,就印证了上面 浅拷贝只是使用了原始元素的引用,也就是说他和a[2] 指向的是同一块内存
而深拷贝是重新生成了一个对象
我们可以用如下方法查看一下
print('id(a[2])',id(a[2])) print('id(b[2])', id(b[2])) print('id(c[2])', id(c[2])) 输出结果: id(a[2]) 2007144113600 id(b[2]) 2007144113600 id(c[2]) 2007144113408
然后,我们给 a[0] =2,此时b[0],c[0] 元素值仍然等于1,这就引出了一个点:深拷贝和浅拷贝都是针对可变数据类型
python 有六大数据类型: 可变--list,dict,set 不可变--Number, String,Tuple
而python 有一个对象缓存机制:
Python有一个缓存对象的机制,以便重复使用。例如当我们创建多个等于1的引用时,实际上是让所有这些引用指向同一个对象,以达到节省资源的目的 python会对-5-256(包括256)的整型数据和短字符串进行缓存
而当我们把1改成2时,实际是开辟了一块新的缓存地址
我们同样可以用id()来查看a[0],b[0],c[0] 的地址,你会发现 只有a[0] 的地址发生了改变
print('id(a[0])',id(a[0])) print('id(b[0])', id(b[0])) print('id(c[0])', id(c[0])) 运行结果: 改变前: id(a[0]) 2878205028656 id(b[0]) 2878205028656 id(c[0]) 2878205028656 改变后: id(a[0]) 2878205028720 id(b[0]) 2878205028656 id(c[0]) 2878205028656
1.深拷贝和浅拷贝的区别:有没有拷贝子对象
2.深拷贝和浅拷贝的使用场景
浅拷贝
- 使用切片操作[:]
- 使用工厂函数(如list/dict/set)
- copy模块的copy()方法
def test_copy_fun3(): l1=[1,[2,3],{'name':'lily'}] l2=list(l1) #list()属于浅拷贝 l3=l1[0:3:1] #切片属于浅拷贝 print('id(l1)=',id(l1)) print('id(l2)=',id(l2)) print('id(l3)=', id(l3)) l1[1].append(4) print('l1=', l1) print('l2=', l2) print('l3=', l3) 运行结果: id(l1)= 3012146690944 id(l2)= 3012095536384 id(l3)= 3012146690240 l1= [1, [2, 3, 4], {'name': 'lily'}] l2= [1, [2, 3, 4], {'name': 'lily'}] l3= [1, [2, 3, 4], {'name': 'lily'}]
3.赋值
赋值和深拷贝,浅拷贝是有区别的,赋值语句并没有生成新的容器,看下面的例子
def test_fun(): a = [1, "hello", [2, 3]] b = a print('\nid(a)=',id(a)) # 外面容器拷贝了,所以a和b的id不一样 print('id(b)=',id(b)) a[2].append(4) a[0]=2 print('id(a[2])',id(a[2])) print('id(b[2])', id(b[2])) print('a=',a) print('b=',b) 运行结果 id(a)= 1524765088576 id(b)= 1524765088576 id(a[2]) 1524765094464 id(b[2]) 1524765094464 a= [2, 'hello', [2, 3, 4], {'key': '123'}] b= [2, 'hello', [2, 3, 4], {'key': '123'}]
posted on 2021-03-04 13:22 kimber_kimber 阅读(32) 评论(0) 编辑 收藏 举报