Python 赋值、浅拷贝和深拷贝
初学Python,和C++还是有许多不同。直接赋值、浅拷贝和深拷贝,这三种拷贝对象的操作之间还是有许多的区别。Python语言的版本为2.7,在Pycharm中进行实验。
一、直接赋值
用下面的代码来实验:
1 origin = [1, "string", [1, 3, 5]] 2 Copy = origin 3 print Copy 4 print id(origin), id(Copy) 5 Copy[0] = 5 6 print origin, Copy 7 Copy[1] = "changed" 8 print origin, Copy 9 Copy[2][0] = 111 10 print origin, Copy 11 print id(origin), id(Copy)
运行的结果如下:
[1, 'string', [1, 3, 5]] 38994824 38994824 [5, 'string', [1, 3, 5]] [5, 'string', [1, 3, 5]] [5, 'changed', [1, 3, 5]] [5, 'changed', [1, 3, 5]] [5, 'changed', [111, 3, 5]] [5, 'changed', [111, 3, 5]] 38994824 38994824
可见,直接赋值的新变量完完全全就是一个原对象的引用,任何对复制对象的引用都会影响到原对象。
二、浅拷贝
用相同的代码来测试,仅仅把拷贝方式改成了copy.copy():
1 import copy 2 origin = [1, "string", [1, 3, 5]] 3 Copy = copy.copy(origin) 4 print Copy 5 print id(origin), id(Copy) 6 Copy[0] = 5 7 print origin, Copy 8 Copy[1] = "changed" 9 print origin, Copy 10 Copy[2][0] = 111 11 print origin, Copy 12 print id(origin), id(Copy)
运行的结果如下:
[1, 'string', [1, 3, 5]] 39453768 39510280 [1, 'string', [1, 3, 5]] [5, 'string', [1, 3, 5]] [1, 'string', [1, 3, 5]] [5, 'changed', [1, 3, 5]] [1, 'string', [111, 3, 5]] [5, 'changed', [111, 3, 5]] 39453768 39510280
这次可以发现,两个对象指向的内存并不相同,也就是说,浅拷贝的对象是一个新的对象。另外,可以发现,对新对象的元素进行替换并不会影响到原对象,而对子对象——列表的修改会影响到原对象。
三、深拷贝
同样,只是把拷贝方式换成copy.deepcopy():
1 import copy 2 origin = [1, "string", [1, 3, 5]] 3 Copy = copy.deepcopy(origin) 4 print Copy 5 print id(origin), id(Copy) 6 Copy[0] = 5 7 print origin, Copy 8 Copy[1] = "changed" 9 print origin, Copy 10 Copy[2][0] = 111 11 print origin, Copy 12 print id(origin), id(Copy)
结果如下:
[1, 'string', [1, 3, 5]] 39978056 39994504 [1, 'string', [1, 3, 5]] [5, 'string', [1, 3, 5]] [1, 'string', [1, 3, 5]] [5, 'changed', [1, 3, 5]] [1, 'string', [1, 3, 5]] [5, 'changed', [111, 3, 5]] 39978056 39994504
同样,两个对象指向的内存位置并不相同,说明创建了新对象。此外,新对象的任何改动都不影响到原有的对象。
结论:
(1)直接赋值是一个完完全全的引用,对新变量的任何改动都会影响到原对象。
(2)浅拷贝创建了新的对象,但是只拷贝了序列的元素,对于元素也是一个序列的情况(即子对象),只复制了对这个序列的引用!
(3)深拷贝是完完全全的拷贝,把原对象完整地拷贝到了新对象中。
实际上,可以更形象的举个栗子:
浅拷贝:
a = [1.1, 2.2] # a = [1.1, 2.2]
b = [1, 2, a] # b = [1, 2, [1.1, 2.2]]
c = b.copy() # c = [1, 2, [1.1, 2,2]]
a[0] = 1.123
b = [1, 2, [1.123, 2.2]]
c = [1, 2, [1.123, 2.2]]
内存中的指向是这样的,如下图:

深拷贝:
注:使用deepcoyp前需要导入copy模块。
Import copy # 导入copy模块
a = [1.1, 2.2] # a = [1.1, 2.2]
b = [1, 2, a] # b = [1, 2, [1.1, 2.2]]
c = b.deepcopy() # c = [1, 2, [1.1, 2,2]]
a[0] = 1.123
b = [1, 2, [1.123, 2.2]]
c = [1, 2, [1.1, 2.2]]
内存中的指向是这样的,如下图:

浅拷贝有什么应用场景?
浅拷贝对于创建联合账号有用,如夫妻共同的银行账号。
import copy unionID = ['username', ['money', 500]] husband = unionID[:] wife = copy.copy(unionID) husband[0] = 'liming' wife[0] = 'hanmeimei' print('-----原始账户-----') print(husband) print(wife) print('-----修改husband-----') husband[1][1] = 600 print(husband) print(wife) print('------修改wife------') wife[1][1] = 1000 print(husband) print(wife)
-----原始账户-----
['liming', ['money', 500]]
['hanmeimei', ['money', 500]]
-----修改husband-----
['liming', ['money', 600]]
['hanmeimei', ['money', 600]]
------修改wife------
['liming', ['money', 1000]]
['hanmeimei', ['money', 1000]]

浙公网安备 33010602011771号