# -*- coding:UTF-8 -*- #此次练习主要是讨论对象的浅复制和深复制 import copy #浅复制一个object有三种方式:1、slice操作; # 2、copy模块的copy函数; # 3、工厂函数:dict()、list()、tuple() #***********************浅复制********************************* #浅复制没有完全的复制一个对象,只是创建一个指向原来对象的reference #比如: origList = ['name',['linkin','age']] #原来列表的元素有两个:string 和 list 类型 #接下来进行三种方式的浅复制: frtList = origList[:] secList = copy.copy(origList) thrList = list(origList) #虽然此时三个list的内存地址都是不一样的,但是list中各个元素与origList的 #各个元素的内存地址都是一样的,只是原来列表元素的reference! #查看四个列表的元素: for x in (origList,frtList,secList,thrList): print x print ''' stdout: ['name', ['linkin', 'age']] ['name', ['linkin', 'age']] ['name', ['linkin', 'age']] ['name', ['linkin', 'age']] ''' #查看内存地址: for x in (origList,frtList,secList,thrList): print id(x), #不一样的容器对象地址,其内容本质是一样的引用 print print '以上是四个list的内存地址' #输出结果: # 28078688 33755424 33537200 33536760(表面:不一样的容器内存地址) #查看三个list对象元素的内存地址: for x in (origList,frtList,secList,thrList): for elements in x: print id(elements), print print '以上是四个list改变前所有元素对象(2个)的内存地址' '''输出结果:(未对各个对象做任何改动,只是单纯的进行浅复制) 19580064 35853776 19580064 35853776 19580064 35853776 19580064 35853776 (本质:一样的元素内存地址(表明只是复制 的对象只是创建一个新的容器,里面的 复制元素只是指向原来origList列表元素的引用)) ''' #针对浅复制的操作,对某一个列表的元素进行操作时,其他的列表对应的元素也会发生改变 #i.e. frtList[1][0] = 'changes' for x in (origList, frtList,secList,thrList): print x print #结果: ''' ['name', ['changes', 'age']] ['name', ['changes', 'age']] ['name', ['changes', 'age']] ['name', ['changes', 'age']] 结果的改变只是因为列表改变的元素是mutable对象 list 如果改变的是immutable对象(string\ int(tuple稍后再讨论)),那么对其他的列表对象没有任何影响 ''' #例如: frtList[0] = 'changeimmutableElems' for x in (origList, frtList,secList,thrList): print x print ''' 输出结果: ['name', ['changes', 'age']] ['changeimmutableElems', ['changes', 'age']] ['name', ['changes', 'age']] ['name', ['changes', 'age']] ''' #查看内存地址: print '以下是改变第二list对象frtList后各个列表所有元素的内存地址:' for x in (origList, frtList,secList,thrList): for elements in x: print id(elements), print '''结果: 19580064 35853776 35846816 35853776 被改变的元素(immutable对象)内存地址改变 19580064 35853776 19580064 35853776 原因:因为string类型是immutable类型,想要对不可改变类型进行改变?那么只有重新创建 string类型的字符串再赋值给frtList[0],那么此时frtList[0]元素内存地址已经改变 然而,如果元素师mutable类型如 list类型,其元素的改变是允许的,改变后的list对象 的内存地址还是不变(因为是mutable类型),所以引用发生改变,其他的浅复制元素引用 也发生改变 ''' #************************************深复制**************************** #进行对象的深复制只需要使用deepcopy函数: deepList = copy.deepcopy(origList) print '深复制之后(改变前)的列表对象内存地址和内容:' for x in (origList,deepList): print id(x),'-->',x print print '改变前列表元素的内存地址和内容:' for x in (origList,deepList): for item in x: print id(item),'-->',item print '''stdout: 深复制之后(改变前)的列表对象内存地址和内容: 28602976 --> ['name', ['changes', 'age']] 34150600 --> ['name', ['changes', 'age']] 改变前列表元素的内存地址和内容: 23184544 --> name 34149240 --> ['changes', 'age'] 23184544 --> name 34151240 --> ['changes', 'age'] ''' #分别对string、list类型的元素进行改变: print '深复制之后(改变后)的列表对象元素内存地址和内容:' deepList[0] = 'strchanges' deepList[1][0] = 'listchanges' for x in (origList,deepList): print id(x),'-->',x print print '改变后列表元素的内存地址和内容:' for x in (origList,deepList): for item in x: print id(item),'-->',item print ''' stdout: 深复制之后(改变后)的列表对象元素内存地址和内容: 28602976 --> ['name', ['changes', 'age']] #两个列表互不影响!! 34150600 --> ['strchanges', ['listchanges', 'age']] 改变后列表元素的内存地址和内容: 23184544 --> name 34149240 --> ['changes', 'age'] 34175136 --> strchanges 34151240 --> ['listchanges', 'age'] '''