Python 物件序列化 (Pickle)


物件序列化是指將物件的狀態轉換為位元組流的過程。建立後,此位元組流可以進一步儲存在檔案中或透過套接字等傳輸。另一方面,從位元組流重建物件稱為反序列化。

Python 對序列化和反序列化的術語分別是 pickling 和 unpickling。Python 標準庫中提供的 pickle 模組提供序列化 (dump() 和 dumps()) 和反序列化 (load() 和 loads()) 函式。

pickle 模組使用非常特定於 Python 的資料格式。因此,並非用 Python 編寫的程式都能夠正確反序列化編碼(pickled)的資料。而且,從未經身份驗證的來源反序列化資料也不被認為是安全的。

pickle 協議

協議是在將 Python 物件構造到/從二進位制資料中使用的約定。目前,pickle 模組定義了 5 種不同的協議,如下所示:

協議版本 0原始的“人類可讀”協議,與早期版本向後相容。
協議版本 1舊的二進位制格式,也與早期版本的 Python 相容。
協議版本 2在 Python 2.3 中引入,提供對新式類的有效 pickling。
協議版本 3在 Python 3.0 中新增。當需要與其他 Python 3 版本相容時推薦使用。
協議版本 4在 Python 3.4 中新增。它增加了對超大型物件的 supports。

要了解 Python 安裝的最高和預設協議版本,請使用 pickle 模組中定義的以下常量。

>>> import pickle
>>> pickle.HIGHEST_PROTOCOL
4
>>> pickle.DEFAULT_PROTOCOL
3

如前所述,pickle 模組的 dump() 和 load() 函式執行 Python 資料的 pickling 和 unpickling。dump() 函式將 pickled 物件寫入檔案,load() 函式將資料從檔案 unpickle 到 Python 物件。

以下程式將字典物件 pickle 到二進位制檔案。

import pickle
f = open("data.txt","wb")
dct = {"name":"Ravi", "age":23, "Gender":"M","marks":75}
pickle.dump(dct,f)
f.close()

執行上述程式碼時,字典物件的位元組表示將儲存在 data.txt 檔案中。

要將資料從二進位制檔案 unpickle 或反序列化回字典,請執行以下程式

import pickle
f = open("data.txt","rb")
d = pickle.load(f)
print (d)
f.close()

Python 控制檯顯示從檔案中讀取的字典物件

{'age': 23, 'Gender': 'M', 'name': 'Ravi', 'marks': 75}

pickle 模組還包含 dumps() 函式,該函式返回 pickled 資料的字串表示形式。

>>> from pickle import dump
>>> dct = {"name":"Ravi", "age":23, "Gender":"M","marks":75}
>>> dctstring = dumps(dct)
>>> dctstring
b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\x04\x00\x00\x00Raviq\x02X\x03\x00\x00\x00ageq\x03K\x17X\x06\x00\x00\x00Genderq\x04X\x01\x00\x00\x00Mq\x05X\x05\x00\x00\x00marksq\x06KKu.'

使用 loads() 函式 unpickle 字串並獲取原始字典物件。

>>> from pickle import load
>>> dct = loads(dctstring)
>>> dct
{'name': 'Ravi', 'age': 23, 'Gender': 'M', 'marks': 75}

pickle 模組還定義了 Pickler 和 Unpickler 類。Pickler 類將 pickle 資料寫入檔案。Unpickler 類從檔案讀取二進位制資料並構造 Python 物件

要寫入 Python 物件的 pickled 資料

from pickle import pickler
f = open("data.txt","wb")
dct = {'name': 'Ravi', 'age': 23, 'Gender': 'M', 'marks': 75}
Pickler(f).dump(dct)
f.close()

透過 unpickle 二進位制檔案讀取資料

from pickle import Unpickler
f = open("data.txt","rb")
dct = Unpickler(f).load()
print (dct)
f.close()

所有 Python 標準資料型別的物件都是可 pickling 的。此外,自定義類的物件也可以被 pickle 和 unpickle。

from pickle import *
class person:
def __init__(self):
self.name = "XYZ"
self.age = 22
def show(self):
print ("name:", self.name, "age:", self.age)
p1 = person()
f = open("data.txt","wb")
dump(p1,f)
f.close()
print ("unpickled")
f = open("data.txt","rb")
p1 = load(f)
p1.show()

Python 庫還具有 marshal 模組,用於 Python 物件的內部序列化。

更新於:2020年6月27日

939 次檢視

啟動您的 職業生涯

透過完成課程獲得認證

開始學習
廣告