copy模块包括创建复合对象(包括列表、元组、字典和用户定义对象的实例)的深浅复制的函数。浅复制是copy函数,深拷贝是deepcopy函数。
对于不可变类型而言(元祖、字符串、数值等),深浅拷贝都是一样的,因为它们的值不能改变,要改变就只能新建一个对象,所以深浅拷贝都是一样的效果。
copy函数
浅复制copy函数其实是新创建了一个对象,但是对于对象里面的元素,拷贝过来的对象还是使用之前对象的引用,我们来看一下下面这个例子:
>>> import copy
>>> a = [1,2,3,[4,5]]
>>> b = copy.copy(a)
>>> id(a)
140305401981624
>>> id(b)
140305401982200
上面例子中两个对象的id不一样,证明copy函数返回的是一个新创建的对象,而不是旧对象a的引用。
>>> import copy
>>> a = [1,2,3,[4,5]]
>>> b = copy.copy(a)
>>> id(a[3])
140305401898624
>>> id(b[3])
140305401898624
>>> a[3].append(6)
>>> a
[1, 2, 3, [4, 5, 6]]
>>> b
[1, 2, 3, [4, 5, 6]]
>>> a[0] = 10
>>> a
[10, 2, 3, [4, 5, 6]]
>>> b
[1, 2, 3, [4, 5, 6]]
上面的例子我们可以看到,对于列表中的元素而言,a和b中的第四个元素拥有相同的id,所以它们是指向同一个内存空间,改变其中一个的值,另一个会随之而改变。但是我们可以看到,改变a中第一个元素的值为10,b中第一个元素值仍然为1,这是因为整数是不可变类型,改变它的值就等于重新创建了一个整数对象,a的第一个元素指向新的整数对象,而b中的第一个元素仍然指向旧的对象,自然也就不一样。
deepcopy
深拷贝自然我们就可以想到,对于对象中的元素,它也会开辟新的对象空间,创建新的对象,那么,原始对象和新的对象之间就完全没有关系了。
>>> import copy
>>> a = [1,2,3,[4,5]]
>>> b = copy.deepcopy(a)
>>> id(a)
140305401898912
>>> id(b)
140305401899272
>>> id(a[3])
140305401816704
>>> id(b[3])
140305401981624
>>> a[3].append(6)
>>> a
[1, 2, 3, [4, 5, 6]]
>>> b
[1, 2, 3, [4, 5]]