博客参考:点击这里
python中对象的复制以及浅拷贝,深拷贝是存在差异的,这儿我们主要以可变变量来演示,不可变变量则不存在赋值/拷贝上的问题(下文会有解释),具体差异如下文所示
1.赋值:
1 a=[1,2,3] 2 b=a 3 a.append('3') 4 print 'b=',b
实例输出结果如下:
1 b= [1, 2, 3, '3']
这儿我们只对列表a进行了操作,但列表b也随之改变,根本原因是在进行赋值操作的时候,变量a与变量b指向了相同的内存地址,实例如下:
1 #coding=utf-8 2 a=[1,2,3] 3 b=a 4 print "变量a的内存地址:",id(a) #获取变量的内存地址 5 print "变量b的内存地址:",id(b) 6 a.append(4) 7 print "变量a的内存地址:",id(a) 8 print "变量b的内存地址:",id(b)
输出结果如下:
1 变量a的内存地址: 39012592 2 变量b的内存地址: 39012592 3 变量a的内存地址: 39012592 4 变量b的内存地址: 39012592
以上结果可以看出进行赋值操作时变量与变量b的内存地址一致,故而在变量a值发生改变时,变量b的值也随之改变。
但这种情况只针对可变变量,str属于不可变变量,值发生改变的时候会重新申请新的地址,实例如下:
1 #coding=utf-8 2 a='123' 3 print ' 变量a的内存地址:',id(a) 4 a='234' 5 print ' 变量a的内存地址:',id(a)
输出结果如下:
1 变量a的内存地址: 38734832 2 变量a的内存地址: 38734856
2.浅拷贝(copy.copy())
1 #coding=utf-8 2 import copy 3 a=[1,2,3] 4 b=copy.copy(a) 5 print ' 变量a的内存地址:',id(a) 6 print ' 变量b的内存地址:',id(b) 7 a.append(4) 8 print b
输出结果:
1 变量a的内存地址: 38160664 2 变量b的内存地址: 38203224 3 [1, 2, 3]
因为变量a与变量b的内存地址不一样,故而在变量a发生改变时,变量b未改变,但因为浅拷贝依然会使用原始变量中元素的地址,实例如下:
1 #coding=utf-8 2 import copy 3 a=[1,2,3] 4 b=copy.copy(a) 5 for i in range(0,len(a)): 6 print ' 变量a中第%d的内存地址:%d'%(i,id(a[i])) 7 for i in range(0,len(b)): 8 print ' 变量b中第%d的内存地址:%d'%(i,id(b[i]))
输出结果:
1 变量a中第0的内存地址:33860840 2 变量a中第1的内存地址:33860828 3 变量a中第2的内存地址:33860816 4 变量b中第0的内存地址:33860840 5 变量b中第1的内存地址:33860828 6 变量b中第2的内存地址:33860816
由输出结果可知,变量a和变量b中的元素的内存地址是一致的,当变量a中存在可变元素时,对可变元素进行更改,变量b依然会同时进行更改,实例如下:
1 #coding=utf-8 2 import copy 3 a=[1,2,3,[11,2,3]] 4 b=copy.copy(a) 5 print '变量a修改前,b的内容:',b 6 a[3].append(4) 7 print '变量a修改后,b的内容:',b
输出如下:
1 变量a修改前,b的内容: [1, 2, 3, [11, 2, 3]] 2 变量a修改后,b的内容: [1, 2, 3, [11, 2, 3, 4]]
3.深拷贝(copy.deepcopy())
1 #coding=utf-8 2 import copy 3 a=[1,2,3,[11,2,3]] 4 b=copy.deepcopy(a) 5 for i in range(0,len(a)): 6 print ' 变量a中第%d的内存地址:%d'%(i,id(a[i])) 7 for i in range(0,len(b)): 8 print ' 变量b中第%d的内存地址:%d'%(i,id(b[i]))
输出如下:
1 变量a中第0的内存地址:30518504 2 变量a中第1的内存地址:30518492 3 变量a中第2的内存地址:30518480 4 变量a中第3的内存地址:38553880 5 变量b中第0的内存地址:30518504 6 变量b中第1的内存地址:30518492 7 变量b中第2的内存地址:30518480 8 变量b中第3的内存地址:38643072
变量a与变量b中的每一个元素的内存地址都不相同,故而变量a发生改变时,变量b不会随之改变。
总结:
1.赋值,浅拷贝,深拷贝只针对可变变量,如list,dict,tuple
2.python中赋值都是进行内存地址的传递
3.浅拷贝(copy,copy())只会赋值对象,重新申请内存地址,但对于对象中的元素依然是原始的内存地址引用
4.如果要完全拷贝一个对象,请使用copy.deepcopy()
写在后面:
每天写一点,总有一天我这条咸鱼能变得更咸