(睁眼就会)Python中深拷贝与浅拷贝的区别:

当对象是不可变的时候:(数字,字符串,元组)

深浅拷贝的区别:是没有区别,挺简单的吧
无论是深或浅拷贝,都是一样的值和id标识;
栗子:

import copy
a = (1,2,3)
b = a #赋值,相当于引用, = 浅拷贝:值相等,地址相等
c = copy.copy(a)
d = copy.deepcopy(a)
print(f'{a},{b},{c},{d}')#值一样,(1, 2, 3),(1, 2, 3),(1, 2, 3),(1, 2, 3)
print(f'{id(a)},{id(b)},{id(c)},{id(d)}')#id一样,139988431308352,139988431308352,139988431308352,139988431308352
print(f'{id(a[0])},{id(b[0])},{id(c[0])},{id(d[0])}')#id一样,94116896809440,94116896809440,94116896809440,94116896809440

当对象为可变的时候: (列表,字典)

深浅拷贝的区别:有区别

先是,浅拷贝:
当没有子对象的时候,浅拷贝拷贝父对象。
当有子对象时时候,浅拷贝拷贝父对象,子对象不拷贝,大家一起共同引用。
值一样,id不一样;

接着是深拷贝:
全部拷贝,就是开辟新的内存,没有引用。
值一样,id不一样;

import copy
a1 = [1,2,3]
b1 = copy.copy(a1)
c1=copy.deepcopy(a1)
print(a1,b1,c1)#值一样,[1, 2, 3] [1, 2, 3] [1, 2, 3]
print(id(a1),id(b1),id(c1))#id不一样,140243294805824 140243294803520 140243294992768
print(id(a1[0]),id(b1[0]),id(c1[0]))#元素id是一样的,93902628225504 93902628225504 93902628225504
#
#当列表中的元素是可变的对象,浅拷贝只会拷贝父对象,子对象不拷贝,子对象相当于引用,一旦改变,原对象和拷贝对象都发生改变
a2 = [[1,2],3]
b2 = copy.copy(a2)
c2 =copy.deepcopy(a2)
d2 = a2[:]#切片也是一种深拷贝
print(a2,b2,c2)#值一样,[[1, 2], 3] [[1, 2], 3] [[1, 2], 3]
print(id(a2),id(b2),id(c2))#id不一样,140029336099712 140029336099776 140029336099840
print(id(a1[0]),id(b1[0]))#这个子对象相当于引用,id和值都一样的,93980016447968 93980016447968
a2[0][0]=2#改变可变元素时,即引用部分
print(a2,b2)#值一样,[[2, 2], 3] [[2, 2], 3]
a2[1]=4#改变不可变元素时
print(a2,b2)#值不一样,[[2, 2],4] [[2, 2], 3]

#

总结

对于不可变对象的深浅拷贝:

不可变对象类型,没有被拷贝的说法,即便是用深拷贝,查看id的话也是一样的,如果对其重新赋值,也只是新创建一个对象,替换掉旧的而已。

一句话就是,不可变类型,不管是深拷贝还是浅拷贝,地址值和拷贝后的值都是一样的。

对于可变对象深浅拷贝:

=浅拷贝:值相等,地址相等
copy浅拷贝:值相等,地址不相等
deepcopy深拷贝:值相等,地址不相等

参考:https://blog.csdn.net/u014745194/article/details/70271868

猜你喜欢

转载自blog.csdn.net/weixin_44683255/article/details/122693455