很多時候,我們需要將內存中的數據,比如字典、列表等保存成文件,以便於存儲和後續的使用。Python中的Pickle模塊就提供了這一功能:將對象保存到文件中或者從文件還原對象。
Pickle可以將Python對象序列化或者反序列化。序列化是指將一個內存對象轉換成字節流,從而可以進行存儲和傳輸。同時,被序列化的字節流可以被反序列化回原來的內存對象。當我們需要對數據做持久化操作時,可以用pickle將數據存成文件、通過網絡進行傳輸或者存到數據庫中。
哪些數據類型可以被pickle序列化呢?你可以pickle如下數據類型:
- Booleans,
- Integers,
- Floats,
- Complex numbers,
- (normal and Unicode) Strings,
- Tuples,
- Lists,
- Sets, and
- Dictionaries that ontain picklable objects.
同時,定義在模塊中最外層的類和函數也可以被pickle。
但是,像generator,inner class,lambda函數則不能直接被pickle,而是需要使用額外的包。
下面,我們就來看一下如何將數據pickle到文件中。
首先,需要導入pickle模塊
import pickle
作為例子,我們準備pickle一個簡單的字典,其中包含可一些key:value對。然後我們將從文件中加載這個字典。
dogs_dict = { 'Ozzy': 3, 'Filou': 8, 'Luna': 5, 'Skippy': 10, 'Barco': 12, 'Balou': 9, 'Laika': 16 }
為了將字典寫入文件,我們用open()函數以“wb”模式打開一個文件,文件名為“dog”。這意味著我們將向文件中寫入二進制數據。
filename = 'dogs'
outfile = open(filename,'wb')
接下來通過pickle.dump()函數將字典寫入到文件中。最後別忘了將文件關閉。
pickle.dump(dogs_dict,outfile)
outfile.close()
這樣,字典數據會寫入到當前目錄下。當然,我們也可以指定輸出文件的路徑。
接下來,我們要將存儲到文件中的數據再恢復成內存對象。與寫文件的過程類似,我們先是打開要讀取的文件,但是是以讀二進制的模式。然後通過pickle.load()函數將文件中的字節流還原成Python對象。最後將文件關閉。
infile = open(filename,'rb')
new_dict = pickle.load(infile)
infile.close()
為了驗證返回的對象是否與存入的相同, 我們可以將其類型和值打印出來
print(new_dict)
print(new_dict==dogs_dict)
print(type(new_dict))
輸出為
{'Ozzy': 3, 'Filou': 8, 'Luna': 5, 'Skippy': 10, 'Barco': 12, 'Balou': 9, 'Laika': 16}
True
有的時候,對於比較大的數據集,我們想要節省一點存儲空間。這是可以通過bzip2或者gzip將pickle的數據進行壓縮
import bz2
import pickle
sfile = bz2.BZ2File('smallerfile', 'w')
pickle.dump(dogs_dict, sfile)
最後,需要注意的是,由於pickle使用的是Python特有的協議,因此不同語言間的兼容性是無法保證的。同時,不同Python版本間也存在著一定的兼容性問題。因此,我們在使用過程中最要要確保Python版本的一致。