python:浅拷贝和深拷贝
**首先直接上结论: —–我们寻常意义的复制就是深复制,即将被复制对象完全再复制一遍作为独立的新个体单独存在。所以改变原有被复制对象不会对已经复制出来的新对象产生影响。
—–而浅复制并不会产生一个独立的对象单独存在,他只是将原有的数据块打上一个新标签,所以当其中一个标签被改变的时候,数据块就会发生变化,另一个标签也会随之改变。这就和我们寻常意义上的复制有所不同了。**
对于简单的 object,用 copy 和 deep copy 没区别
复杂的 object, 如 list 中套着 list 的情况,copy 中的 子list,并未从原 object 真的「独立」出来。也就是说,如果你改变原 object 的子 list 中的一个元素,你的 copy 就会跟着一起变。这跟我们直觉上对「复制」的理解不同。
因此引出这个概念
- 不可变对象:当有需要改变对象内部的值的时候,python就会为对象新建一个id。
- 可变对象:当有需要改变对象内部的值的时候,这个对象的id不发生变化。
常见的不可变对象的有int,str,bool,float,None,tuple,bytes,frozenset-数值型,字符型,元组。
常见的可变对象有 list,dict,set,bytearray-列表,字典,集合。
浅copy
import copy
# 不可变对象:当有需要改变对象内部的值的时候,python就会为对象新建一个id。
# 可变对象:当有需要改变对象内部的值的时候,这个对象的id不发生变化。
a=[1,2,[3,4],{'a':2}]
b=copy.copy(a)
# 改变不可变的值,常见的不可变对象的有int,str,bool,float,None,tuple,bytes,frozenset-数值型,字符型,元组。
a[1]='a'
print(a)
print(b)
print(id(a[1]))
print(id(b[1]))
print('==========================')
# 改变可变的值,常见的可变对象有 list,dict,set,bytearray-列表,字典,集合
b[2][1]='a'
print(a)
print(b)
print(id(a[2]))
print(id(b[2]))
#发现浅copy时并且时可变对象是当我们改了b的值,那么a的也会改变
深copy
import copy
a=[1,2,[3,4]]
c=copy.deepcopy(a)
a[0]='aa'
print(a)
print(c)
print(id(a))
print(id(c))
print('=============')
c[2][0]='a'
print(a)
print(c)
print(id(a))
print(id(c))
#发现深copy时并且时可变对象是当我们改了c的值,那么a的不会改变
结论
直接赋值 :只是将内存地址给了对象。
浅复制:只将父对象拷贝了一遍。
深复制:将父对象与子对象都拷贝了。