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)深拷貝是完完全全的拷貝,把原對象完整地拷貝到了新對象中。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM