1. 程式人生 > >關於Python中深拷貝與淺拷貝的理解(一)---概念

關於Python中深拷貝與淺拷貝的理解(一)---概念


緣由

用Python也有很長時間了,一直在做科學計算和爬蟲採集方面的東西。自己的畢業論文涉及到編寫一個科學計算的軟體,也是用Python編寫。介面採用PyQt

軟體的主體前段時間已經寫好,最近在試算的時候出現兩個問題:

  • 同一種計算方法,點選計算兩次,結果會變,後面再點選幾次結果保持不變
  • 不同的計算方法,第一次改變計算方法可能結果會變,後面再點選幾次結果保持不變
這明顯是個bugbug想我當初寫好了軟體主體,還一時覺得飄飄然,出現了這麼低階的bug瞬間感覺自己學Python一年多還是圖樣。圖樣

不管怎樣,還是要除錯的,所以以上都是廢話,talk is cheap,開擼。

找bug

在我構造的類中,有self.original_data
self.result_data兩組資料,都是Pandas構造的DataFrame。self.original_data是讀取文字儲存的原始資料,而self.result_data則是用於儲存計算得到的結果資料。
重現了幾次bug,之所以出現第二次計算結果變化而後續結果不再變化,應該是輸入資料產生了變化。也就是self.original_data。而我程式中也沒有對於輸入資料的改動。思來想去……結合以前自己閒著沒事看的一些技術部落格和微信公眾號的推送(所以沒事多看點東西還是挺重要),將問題鎖定在了Python的深拷貝和淺拷貝上。

Python中的深拷貝與淺拷貝概念

其實這個問題在學習Python的過程中應該是一個基礎問題,但由於當時沒有在意,以至於後面成型軟體要整體上進行修改。
網上關於Python深拷貝與淺拷貝的相關介紹有很多,這裡列兩個: 大體上講,Python裡的賦值符號“=”只是將物件進行了引用,如果想新開闢地址new出一個新物件,要用copy模組的copy.copy(),但是用這個方法得到的物件是新物件,但是資料還是引用。 如果要完全得到一個新的一模一樣的物件,要用copy.deepcopy()方法。這樣,在改變新物件的時候,原物件才能不受影響,也就是保持原始資料不變。一個簡單的例子(轉自:http://www.jb51.net/article/15714.htm):
import copy  
a = [1, 2, 3, 4, ['a', 'b']] #原始物件  
  
b = a #賦值,傳物件的引用  
c = copy.copy(a) #物件拷貝,淺拷貝  
d = copy.deepcopy(a) #物件拷貝,深拷貝  
  
a.append(5) #修改物件a  
a[4].append('c') #修改物件a中的['a', 'b']陣列物件  
  
print 'a = ', a  
print 'b = ', b  
print 'c = ', c  
print 'd = ', d  
輸出為:
a = [1, 2, 3, 4, ['a', 'b', 'c'], 5] 
b = [1, 2, 3, 4, ['a', 'b', 'c'], 5] 
c = [1, 2, 3, 4, ['a', 'b', 'c']] 
d = [1, 2, 3, 4, ['a', 'b']]
還有這篇部落格,解釋得更加詳細一些。 基本就是這樣,Python深拷貝與淺拷貝的概念存與此。