1. 程式人生 > >python中的序列化

python中的序列化

       0.索引 

       1.json序列化變數

       2.numpy序列化ndarray

       3.pickle序列化變數

 

       序列化 (Serialization)是指將物件、資料結構的狀態資訊轉換為可以儲存或傳輸的形式的過程。在序列化期間,物件將其當前狀態寫入到臨時或永續性儲存區。以後,可以通過從儲存區中讀取或反序列化物件的狀態,重新建立該物件。

我們編寫的程式,會涉及到各種各樣的物件、資料結構,它們通常是以變數的形式在記憶體中存在著。當程式執行結束後,這些變數也就會被清理。但我們有時希望能夠在下一次編寫程式時恢復上一次的某個物件(如機器學習中的到結果,需要程式執行較長時間,多次執行時間成本太大),這就需要我們將變數進行持久化的儲存。一種方式是利用檔案讀寫的方式將變數轉化為某種形式的字串寫入檔案內,但需要自己控制儲存格式顯得十分笨拙。更好的方式是通過序列化的方式將變數持久化至本地。

本文主要針對python中的序列化操作進行記錄,定期更新python中的涉及到的序列化問題,以作備忘。

1.json序列化變數

   序列化物件至本地檔案:

   json.dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)

   對應的反序列化方法:

 json.load(fp, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)

   

   序列化物件至字串:

   json.dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)

   對應的反序列化方法:

   json.loads(s, *, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)

  2.numpy序列化ndarray

   序列化array:np.save(file, arr, allow_pickle=True, fix_imports=True)

   序列化並壓縮:np.savez(file, *args, **kwds)
   反序列化array:numpy.load(file, mmap_mode=None, allow_pickle=True, fix_imports=True, encoding='ASCII')
   示例如下:

np.save('/tmp/123.npy', np.array([[1, 2, 3], [4, 5, 6]]))
np.load('/tmp/123.npy')
#array([[1, 2, 3],
#      [4, 5, 6]])
a=np.array([[1, 2, 3], [4, 5, 6]])
b=np.array([1, 2])
np.savez('/tmp/123.npz', a=a, b=b)
data = np.load('/tmp/123.npz')
data['a']
#array([[1, 2, 3],
# [4, 5, 6]])
data.close()

  3.pickle序列化變數

   pickle和json一樣也是python內建的序列化模組。與json相比,pickle的序列化結果雖然不可讀,但其可以直接序列化自定義的物件,甚至連遞迴儲存變數、引用變數都可以序列化,不必再像json一樣設計自定義的jsonEncoder,帶來了極大便利。

   序列化物件至本地:

   pickle.dump(obj, file, protocol=None, *, fix_imports=True)

   對應的反序列化方法:

   pickle.load(file, *, fix_imports=True, encoding=”ASCII”, errors=”strict”)

   示例如下:

import pickle

# An arbitrary collection of objects supported by pickle.包括自定義的物件。
data = {
    'a': [1, 2.0, 3, 4+6j],
    'b': ("character string", b"byte string"),
    'c': {None, True, False}
}

with open('data.pickle', 'wb') as f: # 此處需指定模式為寫入位元組流,因為pickle是將object轉換為二進位制位元組流
    # Pickle the 'data' dictionary using the highest protocol available.
    pickle.dump(data, f, pickle.HIGHEST_PROTOCOL) # 採用最新的協議,擴充套件性較好

with open('data.pickle', 'rb') as f: # 讀入時同樣需要指定為讀取位元組流模式
    # The protocol version used is detected automatically, so we do not
    # have to specify it.
    data = pickle.load(f)