深浅拷贝
变量与对象
- 不可变对象:数字,字符串,元组
- 可变对象:列表,集合,字典
在Python中,对象有类型而变量无类型,变量就像一个标签贴在对象上,随时可以更换。
引用
当创建一个对象,并把它赋值给另一个对象时,Python并没有复制该对象,而是对它做了一个引用,两者在内存中的地址是一样的。
a = [1,2,3]
b = a
print(id(a))
print(id(b))
---------------------
4415205576
4415205576
浅拷贝
浅拷贝可以看做是复制了一个对象本身,但是该对象内部引用的其他对象则不做复制,只是做了引用
#浅拷贝
a = [1,'a',(1,2),[1,2,3],{'a':'qq'}]
b = a.copy()
print(id(a))
print(id(b))#对外层对象做了拷贝操作,所以内存地址不一样
print(id(a[0]),id(a[1]),id(a[2]),id(a[3]),id(a[4]))
print(id(b[0]),id(b[1]),id(b[2]),id(b[3]),id(b[4]))
#对内层对象不做拷贝,只是做了引用,所以内层对象的地址全部一样
b[3].remove(2)
print(a)
print(b)
#对b的内层可变对象进行操作,则所引用的内层对象改变,也影响到了使用它的a
b[0]=3
b[1]='qq'
b[2]=(1,3)
b[3]=[1,4]
b[4]={'b':'bb'}
print(id(a[0]),id(a[1]),id(a[2]),id(a[3]),id(a[4]))
print(id(b[0]),id(b[1]),id(b[2]),id(b[3]),id(b[4]))
#此为对内层对象的赋值操作,则解除了原有的引用,在内存中新建了对象并做引用
---------------------------------------------------
4381594888
4381622408
4378522976 4380346888 4381593864 4381622472 4380220224
4378522976 4380346888 4381593864 4381622472 4380220224
[1, 'a', (1, 2), [1, 3], {'a': 'qq'}]
[1, 'a', (1, 2), [1, 3], {'a': 'qq'}]
4378522976 4380346888 4381593864 4381622472 4380220224
4378523040 4380235064 4381593928 4381439688 4380220296
深拷贝
深拷贝首先对外层对象进行拷贝,内层对象如果是不可变对象,则直接引用,对可变对象进行拷贝
#深拷贝
a = [1,'2',(3,),[4,5],{'6':6}]
import copy
b = copy.deepcopy(a)
print(id(a))
print(id(b))#进行了深拷贝,外层对象自然是拷贝了的
print(id(a[0]),id(a[1]),id(a[2]),id(a[3]),id(a[4]))
print(id(b[0]),id(b[1]),id(b[2]),id(b[3]),id(b[4]))
#深拷贝对内层对象的处理是:不可变对象进行引用,可变对象进行拷贝
------------------------------------------
4567217416
4567062216
4564145504 4567146200 4565412104 4567245000 4565842752
4564145504 4567146200 4565412104 4567245384 4565843184