python——pickle模塊的詳解

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的陣列和實例datetimedate而且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()

運行結果:

接下來就能夠讀取數據進行訓練了。

相關文章
相關標籤/搜索