pickle模塊詳解python
該pickle
模塊實現了用於序列化和反序列化Python對象結構的二進制協議。 「Pickling」是將Python對象層次結構轉換爲字節流的過程, 「unpickling」是反向操做,從而將字節流(來自二進制文件或相似字節的對象)轉換回對象層次結構。pickle
模塊對於錯誤或惡意構造的數據是不安全的。
安全
pickle協議和JSON(JavaScript Object Notation)的區別 :dom
1. JSON是一種文本序列化格式(它輸出unicode文本,雖然大部分時間它被編碼utf-8
),而pickle是二進制序列化格式;函數
2. JSON是人類可讀的,而pickle則不是;工具
3. JSON是可互操做的,而且在Python生態系統以外普遍使用,而pickle是特定於Python的;編碼
默認狀況下,JSON只能表示Python內置類型的子集,而不能表示自定義類; pickle能夠表示極其龐大的Python類型(其中許可能是自動的,經過巧妙地使用Python的內省工具;複雜的案例能夠經過實現特定的對象API來解決)。spa
pickle 數據格式是特定於Python的。它的優勢是沒有外部標準強加的限制,例如JSON或XDR(不能表明指針共享); 可是這意味着非Python程序可能沒法重建pickled Python對象。設計
默認狀況下,pickle
數據格式使用相對緊湊的二進制表示。若是您須要最佳尺寸特徵,則能夠有效地壓縮數據。指針
模塊接口code
要序列化對象層次結構,只需調用該dumps()
函數便可。一樣,要對數據流進行反序列化,請調用該loads()
函數。可是,若是您想要更多地控制序列化和反序列化,則能夠分別建立一個Pickler
或一個Unpickler
對象。
pickle
模塊提供如下常量:
pickle.
HIGHEST_PROTOCOL
整數, 可用的最高協議版本。這個值能夠做爲一個被傳遞協議的價值函數 dump()
和dumps()
以及該Pickler
構造函數。
pickle.
DEFAULT_PROTOCOL
整數,用於編碼的默認協議版本。可能不到HIGHEST_PROTOCOL
。目前,默認協議是3,這是爲Python 3設計的新協議。
pickle
模塊提供如下功能,使酸洗過程更加方便:
pickle.
dump
(obj,file,protocol = None,*,fix_imports = True )
將obj對象的編碼pickle編碼表示寫入到文件對象中,至關於Pickler(file,protocol).dump(obj)
可供選擇的協議參數是一個整數,指定pickler使用的協議版本,支持的協議是0到HIGHEST_PROTOCOL
。若是未指定,則默認爲DEFAULT_PROTOCOL
。若是指定爲負數,則選擇HIGHEST_PROTOCOL
。
文件參數必須具備接受單個字節的參數寫方法。所以,它能夠是爲二進制寫入打開的磁盤文件, io.BytesIO
實例或知足此接口的任何其餘自定義對象。
若是fix_imports爲true且protocol小於3,則pickle將嘗試將新的Python 3名稱映射到Python 2中使用的舊模塊名稱,以便使用Python 2可讀取pickle數據流。
pickle.
dumps
(obj,protocol = None,*,fix_imports = True )
將對象的pickled表示做爲bytes
對象返回,而不是將其寫入文件。
參數protocol和fix_imports具備與in中相同的含義 dump()
。
pickle.
load
(file,*,fix_imports = True,encoding =「ASCII」,errors =「strict」 )
從打開的文件對象 文件中讀取pickle對象表示,並返回其中指定的重構對象層次結構。這至關於Unpickler(file).load()
。
pickle的協議版本是自動檢測的,所以不須要協議參數。超過pickle對象的表示的字節將被忽略。
參數文件必須有兩個方法,一個採用整數參數的read()方法和一個不須要參數的readline()方法。兩種方法都應返回字節。所以,文件能夠是爲二進制讀取而打開的磁盤文件,io.BytesIO
對象或知足此接口的任何其餘自定義對象。
可選的關鍵字參數是fix_imports,encoding和errors,用於控制Python 2生成的pickle流的兼容性支持。若是fix_imports爲true,則pickle將嘗試將舊的Python 2名稱映射到Python 3中使用的新名稱。編碼和 錯誤告訴pickle如何解碼Python 2編碼的8位字符串實例; 這些默認分別爲'ASCII'和'strict'。該編碼能夠是「字節」做爲字節對象讀取這些8位串的實例。使用encoding='latin1'
所需的取儲存NumPy的陣列和實例datetime
,date
而且time
被Python 2解碼。
pickle.
loads
(bytes_object,*,fix_imports = True,encoding =「ASCII」,errors =「strict」 )
從bytes
對象讀取pickle對象層次結構並返回其中指定的重構對象層次結構。
pickle的協議版本是自動檢測的,所以不須要協議參數。超過pickle對象的表示的字節將被忽略。
import numpy as np import pickle import io if __name__ == '__main__': path = 'test' f = open(path, 'wb') data = {'a':123, 'b':'ads', 'c':[[1,2],[3,4]]} pickle.dump(data, f) f.close() f1 = open(path, 'rb') data1 = pickle.load(f1) print(data1)
對於python格式的數據集,咱們就可使用pickle進行加載了,下面與cifar10數據集爲例,進行讀取和加載:
import numpy as np import pickle import random import matplotlib.pyplot as plt from PIL import Image path1 = 'D:\\tmp\cifar10_data\cifar-10-batches-py\data_batch_1' path2 = 'D:\\tmp\cifar10_data\cifar-10-batches-py\data_batch_2' path3 = 'D:\\tmp\cifar10_data\cifar-10-batches-py\data_batch_3' path4 = 'D:\\tmp\cifar10_data\cifar-10-batches-py\data_batch_4' path5 = 'D:\\tmp\cifar10_data\cifar-10-batches-py\data_batch_5' path6 = 'D:\\tmp\cifar10_data\cifar-10-batches-py\\test_batch' if __name__ == '__main__': with open(path1, 'rb') as fo: data = pickle.load(fo, encoding='bytes') # print(data[b'batch_label']) # print(data[b'labels']) # print(data[b'data']) # print(data[b'filenames']) print(data[b'data'].shape) images_batch = np.array(data[b'data']) images = images_batch.reshape([-1, 3, 32, 32]) print(images.shape) imgs = images[5, :, :, :].reshape([3, 32, 32]) img = np.stack((imgs[0, :, :], imgs[1, :, :], imgs[2, :, :]), 2) print(img.shape) plt.imshow(img) plt.axis('off') plt.show()
運行結果:
接下來就能夠讀取數據進行訓練了。