【摘要】本篇博文簡析了何爲pickle模塊,爲什麼要用pickle模塊以及如何使用。
1. pickle模塊簡介
python的pickle模塊實現了python的所有數據序列和反序列化。與JSON不同的是pickle不是用於多種語言間的數據傳輸,它僅作爲python對象的持久化或者python程序間進行互相傳輸對象的方法,因此它支持了python所有的數據類型。
在講JSON模塊的時候,我們就講了序列化與反序列化。那麼到底什麼是序列化呢?
序列化是什麼?
序列化是指將對象、數據結構的狀態信息轉換爲可以存儲或傳輸的形式的過程。在序列化期間,對象將其當前狀態寫入到臨時或持久性存儲區。以後,可以通過從存儲區中讀取或反序列化對象的狀態,重新創建該對象。
序列化的作用是什麼?
我們編寫的程序,會涉及到各種各樣的對象、數據結構,它們通常是以變量的形式在內存中存在着。當程序運行結束後,這些變量也就會被清理。但我們有時希望能夠在下一次編寫程序時恢復上一次的某個對象(如機器學習中的到結果,需要程序運行較長時間,多次運行時間成本太大),這就需要我們將變量進行持久化的存儲。一種方式是利用文件讀寫的方式將變量轉化爲某種形式的字符串寫入文件內,但需要自己控制存儲格式顯得十分笨拙。更好的方式是通過序列化的方式將變量持久化至本地。
2.pickle模塊的序列化與反序列化
我們知道不是所有的python對象都可以轉換爲JSON對象,例如集合、datetime對象等。
請看下面的代碼:
import json
nums = range(1, 10)
print(type(nums))
#json不能成功的序列化
json_nums = json.dumps(nums)
print(json_nums)
就會出現如下報錯:
json不能將range對象序列化。這個時候,就需要用到pickle模塊了,因爲這個模塊支持所有的python數據類型。
pickle模塊序列化
函數 | 描述 |
---|---|
pickle.dumps( ) | 將python對象序列化成pickle的bytes類型數據 |
pickle.dump( ) | 將python對象序列化存入已經打開的文件中 |
【注】
pickle.dump(obj, file,[protocol])
序列化對象,並將結果數據流寫入到文件對象中。參數protocol是序列化模式,默認值爲0,表示以文本的形式序列化。protocol的值還可以是1或2,表示以二進制的形式序列化。
針對上面json無法序列化的range對象,我們看一下pickle模塊是否可以序列化?
import pickle
nums = range(1, 10)
print(type(nums))
pickle_nums = pickle.dumps(nums)
print(pickle_nums)
print("序列化:", type(pickle_nums))
很明顯,pickle模塊可以序列化range對象。
再看看dump()方法
with open ('doc/user.txt','wb') as f:
pickle_numsNew = pickle.dump(nums,f)
特別要注意,以二進制的權限打開文件,因爲序列化後的數據是bytes類型而不是string類型。如果不加b,會報如下錯誤:
打開文件,可以看到序列化後的內容:
pickle模塊反序列化
函數 | 描述 |
---|---|
pickle.loads( ) | 將pickle的bytes類型數據反序列化成python對象 |
pickle.load( ) | 將文件中pickle的bytes類型數據反序列化成python對象 |
unpickle_nums = pickle.loads(pickle_nums)
print(unpickle_nums)
print("反序列化:", type(unpickle_nums))
我們將上面序列化後的bytes類型反序列化爲python對象
load()方法:
從上面doc/user.txt文件中反序列化其中的bytes類型:
with open ('doc/user.txt','rb') as f:
pickle_numsNew = pickle.load(f)
print(pickle_numsNew)
print(type(pickle_numsNew))
【補充】
cPickle是pickle模塊的C語言編譯版本,相對速度更快。
因此,讀者可以這樣做:
import cPickle as pickle
剩下用法是一樣的。
3.JSON和pickle模塊的區別
-
JSON只能處理基本數據類型。pickle能處理所有Python的數據類型。
-
JSON用於各種語言之間的字符轉換。pickle用於Python程序對象的持久化或者Python程序間對象網絡傳輸,但不同版本的Python序列化可能還有差異。
-
json :
序列化(編碼): python對象編碼成json字符串
反序列化(解碼): 將json字符串轉成python對象
pickle:
序列化(編碼): python對象編碼成pickle的bytes類型數據
反序列化(解碼): 將pickle的bytes類型數據轉成python對象