python的深复制和浅复制

# -*- 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']
'''


你可能感兴趣的:(编程,python)