简介
python中关于对象复制有三种类型:直接赋值、浅拷贝和深拷贝,他们既有联系又有区别。在python中,“类型”属于“对象”,“变量”是没有“类型”的。所有的变量都可以理解是内存中一个对象的“引用”。所以,我们需要把“变量”和真正的“内存对象”分开。
直接赋值
在python中赋值语句是建立对象的引用值,而不是复制对象。因此,python变量更像是指针,而不是数据存储区域。因此,直接赋值其实就是其实就是对象的引用(别名)。
浅拷贝(copy)
拷贝父对象,不会拷贝对象的内部的子对象,浅拷贝仅仅复制了容器中元素的地址。
>>> testList = ["a","b","c","d","e"]
>>> testListCopy = testList
>>> testList
['a', 'b', 'c', 'd', 'e']
>>> testListCopy
['a', 'b', 'c', 'd', 'e']
>>> testList.pop(1) ## 删除testList一个元素
'b'
>>> testList
['a', 'c', 'd', 'e']
>>> testListCopy ## testListCopy也发生了改变
['a', 'c', 'd', 'e']
深拷贝(deepcopy)
如果不想出现上面的情况(testListCopy随意testList改变而改变),需要使用深拷贝(deepcopy)方法。
copy模块的deepcopy方法可以完全拷贝了父对象及其子对象。深拷贝不仅仅拷贝了原始对象自身,也对其包含的值进行拷贝,它会递归的查找对象中包含的其他对象的引用,来完成更深层次拷贝。因此,深拷贝产生的副本可以随意修改而不需要担心会引起原始值的改变。
>>> from copy import deepcopy ## 导入copy模块
>>> testList = ["a","b","c","d","e"]
>>> testListDeepCopy = deepcopy(testList)
>>> testList
['a', 'b', 'c', 'd', 'e']
>>> testListDeepCopy
['a', 'b', 'c', 'd', 'e']
>>> testList.pop(0) ## 删除testList中的元素
'a'
>>> testList.pop(1)
'c'
>>> testList
['b', 'd', 'e']
>>> testListDeepCopy ## testListDeepCopy没有发生改变
['a', 'b', 'c', 'd', 'e']
参考链接
理解python里的赋值、引用、拷贝及作用域、内存管理、垃圾回收