Python笔记--深浅copy

写在最前:网上关于python深浅拷贝的内容很多,写的也比较好。而我写这篇主要是想强迫自己总结一下这个主题,也想让自己的理解更深刻一些。

1.python的可变对象和不可变对象

关于python的深浅copy其实跟python中的可变对象和不可变对象有关,所以先来说说这两种对象类型。

可变对象:常见的可变对象有list、dict、set。而不可变对象有:数字,字符串、tuple。

可变对象和不可变对象的主要区别则在于:可变对象可以“原址修改”,也就是说可变对象所指向的内存地址的值是可以发生变化的;而不可变对象所指向的内存地址所保存的值是不能改变的,要改变不可变对象所指向的值,只能重新开辟一块内容空间给它。

>>> a='a'
>>> id(a)
1871343910560
>>> a='b'
>>> id(a)
1871343908880
>>> b=[1]
>>> id(b)
1871353823688
>>> b.append(2)
>>> b
[1, 2]
>>> id(b)
1871353823688

2.深浅拷贝

先说一下深浅拷贝的定义。Python3中“万物皆对象”,浅拷贝只是拷贝了一个对象的引用,所有指向这个对象的变量共用同一段内存地址,其中一个变量的值发生改变,另一个变量的值也会发生改变。而深拷贝是一个变量对另一个变量的值的拷贝,不同的变量占用不同的内存地址,并且变量之间的改变互不影响。

2.1 不可变对象的深浅拷贝

不可变对象是没有深拷贝的,即使是调用深拷贝函数进行拷贝。

>>> from copy import deepcopy
>>> a='a'
>>> id(a)
1805273857696
>>> b=deepcopy('a')
>>> b
'a'
>>> id(b)
1805273857696

2.2 可变对象的深浅拷贝

>>> a=[1,2,[1,2]]
>>> id(a)
2252725804552
>>> b=a
>>> b
[1, 2, [1, 2]]
>>> id(b)
2252725804552
>>> b[0]=3
>>> b
[3, 2, [1, 2]]
>>> a
[3, 2, [1, 2]]
>>> b[2][1]='a'
>>> b
[3, 2, [1, 'a']]
>>> a
[3, 2, [1, 'a']]

从上面的实验结果可以看出,赋值语句的作用是浅拷贝。变量b与变量a的值相等并且地址也相等。变量b发生变化,变量a也跟着变化。

>>> from copy import copy
>>> a=[1,2,[1,2]]
>>> id(a)
1740736217032
>>> b=copy(a)
>>> id(b)
1740736216328
>>> id(a[2])
1740736320264
>>> id(b[2])
1740736320264
>>> b[0]='a'
>>> b
['a', 2, [1, 2]]
>>> a
[1, 2, [1, 2]]
>>> b[2][0]='b'
>>> b
['a', 2, ['b', 2]]
>>> a
[1, 2, ['b', 2]]

从上面的实验结果可以发现,对变量a使用copy复制出b。虽然a和b指向了不同的地址,但是a和b指向的地址中保存的内容完全相同(即列表a和列表b中各个元素的地址)。所以在对b[2][0]修改时,a变量也跟着发生了改变。

>>> from copy import deepcopy
>>> a=[1,2,[1,2]]
>>> id(a)
2102071971656
>>> b=deepcopy(a)
>>> b
[1, 2, [1, 2]]
>>> id(b)
2102071970952
>>> id(a[2])
2102072074568
>>> id(b[2])
2102071971016
>>> b[0]='a'
>>> b
['a', 2, [1, 2]]
>>> a
[1, 2, [1, 2]]
>>> b[2][0]='b'
>>> b
['a', 2, ['b', 2]]
>>> a
[1, 2, [1, 2]]
从上面的实验结果可以发现,deepcopy完全把变量a和变量b分开了,b变量发生改变对变量a没有任何影响。

猜你喜欢

转载自blog.csdn.net/yeshang_lady/article/details/80755061