python中对于对象的拷贝分为浅拷贝(copy)和深拷贝(deepcopy)两种方式。
其中浅拷贝由“=”完成。而深拷贝由copy模块中deepcopy()函数担任。
浅拷贝和深拷贝的区别是:浅拷贝只是将原对象在内存中引用地址拷贝过来了。让新的对象指向这个地址。而深拷贝是将这个对象的所有内容遍历拷贝过来了,相当于跟原来没关系了,所以如果你这时候修改原来对象的值跟他没关系了,不会随之更改。
1.浅拷贝”=”的使用
#1.使用 =复制不可变对象的值, 以及复制以后修改其值后的变化。 val1 = 1000 val2 = val1 print("val1 is :{0},val2 is :{1}".format(val1,val2))#val1 is :1000,val2 is :1000 print(id(val1),id(val2)) #34052192 34052192 #这时候修改val1的值,尽管val2指向val1.但因为val1是不可变类型,修改其值,会重新给新值分配内存,然后指向他。 val1 += 1 print(val1,id(val1),val2,id(val2)) #1001 10131616 1000 10131568 值不一样,内存地址也不一样了 #1.使用=复制可变对象的值,以及复制以后修改其值后的变化。 ls1 =[1,2,3,4] ls2 = ls1 print(id(ls1),id(ls2)) #43702792 43702792 直接使用=复制变量,内存地址一样,值也一样。 print(ls1,ls2) #[1, 2, 3, 4] [1, 2, 3, 4]直接使用=复制变量,内存地址一样,值也一样。 #这时候修改可变对的值,因为其值可变,所以只需要在原内存地址上修改即可。 ls1.append(5) print(id(ls1),id(ls2)) #可变对象修改其值,内存引用不变 print(ls1,ls2) #[1, 2, 3, 4, 5] [1, 2, 3, 4, 5] 因为两个变量的内存指向一样,所以值也一样。
2.深拷贝:copy.deepcopy()函数
#1.使用copy.deepcopy()拷贝不可变对象的值,以及复制以后修改其值后的变化。 val1 = 1000 val2 = copy.deepcopy(val1) print("val1 is :{0},val2 is :{1}".format(val1,val2))#val1 is :1000,val2 is :1000 print(id(val1),id(val2)) #33717408 33717408 对于不可变对象,深度拷贝内存地址没有修改。 val1 += 1 print(val1,id(val1),val2,id(val2)) #1001 33717904 1000 33717408 #1.使用copy.deepcopy()复制可变对象的值,以及复制以后修改其值后的变化。 ls1 =[1,2,3,4] ls2 = copy.deepcopy(ls1) print(id(ls1),id(ls2)) #34628472 34628712 注意对于可变对象深度拷贝后内存地址都修改了。 print(ls1,ls2) #[1, 2, 3, 4] [1, 2, 3, 4] ls1.append(5) print(id(ls1),id(ls2)) #34628472 34628712 print(ls1,ls2) #[1, 2, 3, 4, 5] [1, 2, 3, 4] #注意这个时候ls2的值没有随着ls1修改。
总结:
(1)、其实对于浅拷贝和深拷贝来说,如果拷贝对象都是不可变对象的话,那么两者效果是一样的。
(2)、如果是可变对象的话,“=”拷贝的方式,只是拷贝了内存中的地址引用,两个对象的地址引用一样,所以两个对象的值会随着一方的修改而修改。而对于deepcopy()来说,如果是可变对象的话,那么拷贝内容后新对象的内存地址也会重新分配,跟原来的内存地址不一样了。所以两者任意修改变量的内容不会对另一方造成影响。
3.注意一个特殊的copy(),跟深浅拷贝都有区别,慎用、慎用、慎用。
(1)copy.copy对于可变类型,会进行浅拷贝
(2)copy.copy对于不可变类型,不会拷贝,仅仅是指向
1.使用copy()拷贝不可变对象 val1 = 1000 val2 = copy.copy(val1) print(val1,val2)##1000 1000 print(id(val1),id(val2))#8551568 8551568 2.使用copy()拷贝可变对象 ls1 =[1,2,3,4] ls2 = copy.copy(ls1) ls1.append(5) print(ls1,ls2) #[1, 2, 3, 4, 5] [1, 2, 3, 4] 看上去copy()函数效果和deepcopy()效果一样,可变对象拷贝后值也没有随着一个对象的修改而修改。 然后真实情况真是这样嘛?请看下面的案例,同样是拷贝可变对象。 origin = [1, 2, [3, 4]] cop1 = copy.copy(origin) cop2 = copy.deepcopy(origin) origin[2][0] = "hey!" #修改数据源的值 print(cop1,cop2) #[1, 2, ['hey!', 4]] [1, 2, [3, 4]] 很显然这时copy()函数拷贝的值随着原对象的值修改了,而deepcopy()的值没有随着原对象的值修改。 主要是因为deepcopy会将复杂对象的每一层复制一个单独的个体出来对于copy()函数要慎用,慎用。
今天的文章浅拷贝“=”、 深拷贝deepcopy()、 特殊的copy()函数分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/57208.html