python中的对象复制有好几种方法,之前已经接触过了,今天下午又用到了这个知识点,这里简单的总结一下,赋值、浅拷贝和深拷贝三种方法的差异,简单的一句话,如果说你想“克隆”出来一个跟原对象完全独立但又一模一样的对象时就用深拷贝就行了。下面是具体的实践:
#!usr/bin/env python
# encoding:utf-8
'''
__Author__:沂水寒城
功能: python 赋值、浅拷贝、深拷贝学习
分析:
深拷贝:复制出一个完全独立的新个体对象,原对象改变不会影响新对象
赋值:只是对原对象加了一个新的标签,原对象改变会影响新对象
浅拷贝:当原对象为不可变对象如:数值,字符串,元组时效用与赋值操作等价
当原对象为可变对象如:列表和元组时会产生一个类似独立的对象
'''
import re
import sys
reload(sys)
import copy
sys.setdefaultencoding("utf-8")
def copyFunc():
'''
拷贝学习
'''
tmp_list=[12,56,3,17,[22,33,44,55],(66,77),'china']
print 'tmp_list_id: ',id(tmp_list)
temp=tmp_list
print 'temp_value: ',temp
print 'temp_id: ',id(temp)
surfaceCopy=copy.copy(tmp_list)
print 'surfaceCopy_value: ',surfaceCopy
print 'surfaceCopy_id: ',id(surfaceCopy)
deepCopy=copy.deepcopy(tmp_list)
print 'deepCopy_value: ',deepCopy
print 'deepCopy_id: ',id(deepCopy)
print '----------------------------------------------------------------'
tmp_list.append('American')
tmp_list[0]=999
print 'tmp_list: ',tmp_list
print 'tmp_list_id: ',id(tmp_list)
print 'temp: ',temp
print 'temp_id: ',id(temp)
print 'surfaceCopy: ',surfaceCopy
print 'surfaceCopy_id: ',id(surfaceCopy)
print 'deepCopy: ',deepCopy
print 'deepCopy_id: ',id(deepCopy)
print '----------------------------------------------------------------'
tmp_list[4].append(8888)
print 'tmp_list: ',tmp_list
print 'tmp_list_id: ',id(tmp_list)
print 'temp: ',temp
print 'temp_id: ',id(temp)
print 'surfaceCopy: ',surfaceCopy
print 'surfaceCopy_id: ',id(surfaceCopy)
print 'deepCopy: ',deepCopy
print 'deepCopy_id: ',id(deepCopy)
if __name__=='__main__':
copyFunc()
运行结果如下:
tmp_list_id: 38446280
temp_value: [12, 56, 3, 17, [22, 33, 44, 55], (66, 77), 'china']
temp_id: 38446280
surfaceCopy_value: [12, 56, 3, 17, [22, 33, 44, 55], (66, 77), 'china']
surfaceCopy_id: 38511304
deepCopy_value: [12, 56, 3, 17, [22, 33, 44, 55], (66, 77), 'china']
deepCopy_id: 38446344
----------------------------------------------------------------
tmp_list: [999, 56, 3, 17, [22, 33, 44, 55], (66, 77), 'china', 'American']
tmp_list_id: 38446280
temp: [999, 56, 3, 17, [22, 33, 44, 55], (66, 77), 'china', 'American']
temp_id: 38446280
surfaceCopy: [12, 56, 3, 17, [22, 33, 44, 55], (66, 77), 'china']
surfaceCopy_id: 38511304
deepCopy: [12, 56, 3, 17, [22, 33, 44, 55], (66, 77), 'china']
deepCopy_id: 38446344
----------------------------------------------------------------
tmp_list: [999, 56, 3, 17, [22, 33, 44, 55, 8888], (66, 77), 'china', 'American']
tmp_list_id: 38446280
temp: [999, 56, 3, 17, [22, 33, 44, 55, 8888], (66, 77), 'china', 'American']
temp_id: 38446280
surfaceCopy: [12, 56, 3, 17, [22, 33, 44, 55, 8888], (66, 77), 'china']
surfaceCopy_id: 38511304
deepCopy: [12, 56, 3, 17, [22, 33, 44, 55], (66, 77), 'china']
deepCopy_id: 38446344
[Finished in 0.1s]
这里一共有三次输出执行操作,第一次输出操作是输出了原对象tmp_list经过赋值、浅拷贝和深拷贝三种“克隆”方式得到的新的数据对象结果;第二次输出是对原对象进行修改:增加了最后一个元素以及修改了第一个元素值,数值型和字符型对象都是不可变的对象,所以,原对象的改变只导致了赋值对象的改变,而浅拷贝对象并未发生变化,深拷贝对象由于已经是一个全新的完全独立的对象了所以也不会改变;第三次输出是改变了原对象中的一个可变元素——列表,向列表中增加了一个元素,查看输出结果时发现:除了赋值对象肯定随着原对象变化以外,浅拷贝对象也发生了变化,这是因为修改可变元素,浅拷贝对象也会随之发生变化,此时的深拷贝对象同样是不会发生任何变化的。