1. 程式人生 > >床頭筆記之pickle模組

床頭筆記之pickle模組

pickle模組簡介

  • pickle模組實現了用於序列化和反序列化Python物件結構的二進位制協議。
  • “Pickling”是將Python物件層次結構轉換為位元組流的過程, “unpickling”是反向操作,從而將位元組流(來自二進位制檔案或類似位元組的物件)轉換回物件層次結構。
  • 使用的資料格式pickle是特定於Python的,意味著非Python程式可能無法重建pickle Python物件。

直觀理解:

pickle模組就是把物件(list,set,dict,object等物件)編碼成二進位制(為了儲存),同時又可以從二進位制(快取或者檔案裡)載入即解碼回來成原先的物件。
注意:要是自定義類物件(非list,set,dict等吧內建類)需要先定義好,再載入load,否則會報錯找不到類

其它類似模組:

marshal:

Python有一個更原始的序列化模組marshal,但通常pickle應該始終是序列化Python物件的首選方法。 marshal主要用於支援Python的.pyc 檔案。
比較:

  • 該pickle模組跟蹤它已經序列化的物件,以便稍後對同一物件的引用不會再次序列化。 marshal不這樣做。
  • marshal不能用於序列化使用者定義的類及其例項。 pickle可以透明地儲存和恢復類例項,但是類定義必須是可匯入的,並且與儲存物件時存在於同一模組中。
  • 該marshal序列化格式是不能保證整個Python版本移植。因為它的主要工作是支援
    .pyc檔案,所以Python實施者保留在需要時以非向後相容的方式更改序列化格式的權利。該pickle序列化格式是保證不同的Python版本向後相容。
json:
  • JSON是一種文字序列化格式(它輸出unicode文字,雖然大部分時間它被編碼utf-8),而pickle是二進位制序列化格式;
  • JSON是人類可讀的,而pickle不是;
  • JSON是可互操作的,並且在Python生態系統之外廣泛使用,而pickle是特定於Python的;
  • 預設情況下,JSON只能表示Python內建型別的子集,而不能表示自定義類;
  • pickle可以代表極其龐大的Python型別(其中許多是自動的,通過巧妙地使用Python的內省工具;複雜的案例可以通過實現特定的物件API來解決)。

協議版本號:

目前有5種不同的方案可用於序列化。協議使用的越高,讀取生成的pickle所需的Python版本就越新。

  • 協議版本0是原始的“人類可讀”協議,並且向後相容早期版本的Python。
  • 協議版本1是舊的二進位制格式,它也與早期版本的Python相容。
  • 在Python 2.3中引入了協議版本2。它提供了更有效的新式型別的序列化。參考PEP 307獲取有關協議2帶來的改進的資訊。
  • 在Python 3.0中添加了協議版本3。它對bytes物件有明確的支援, 不能被Python
    2.x開啟。這是預設協議,需要與其他Python 3版本相容時的推薦協議。
  • 在Python 3.4中添加了協議版本4。它增加了對非常大的物件的支援,挑選更多種類的物件,以及一些資料格式優化。參考PEP3154獲取有關協議4帶來的改進的資訊。

注意: 序列化是一種比永續性更原始的概念; 雖然 pickle讀取和寫入檔案物件,但它不處理命名持久物件的問題,也不處理對持久物件的併發訪問(甚至更復雜)的問題。該pickle模組可以將複雜物件轉換為位元組流,並且可以將位元組流轉換為具有相同內部結構的物件。對這些位元組流最明顯的做法可能是將它們寫入檔案,但也可以想象它們通過網路傳送或將它們儲存在資料庫中。該shelve 模組提供了一個簡單的介面,用於在DBM樣式的資料庫檔案上pickle和unpickle物件。

例項:

物件儲存:
def storeTree(inputTree,filename):
    import pickle
    fw = open(filename,'w')
    pickle.dump(inputTree,fw)
    fw.close()
物件載入:
def grabTree(filename):
    import pickle
    fr = open(filename)
    return pickle.load(fr)
python3要加b,以二進位制讀寫才不會報錯:
a=1,{1:'a','b':121},(1,2),[1,2,3]
print(a)

輸出: (1, {1: ‘a’, ‘b’: 121}, (1, 2), [1, 2, 3])

import pickle 
fw = open('filename.pickle','wb')
pickle.dump(a,fw)
fw.close()
fr = open('filename.pickle','rb')
print(pickle.load(fr))

輸出: (1, {1: ‘a’, ‘b’: 121}, (1, 2), [1, 2, 3])

協議版本:
import pickle
pickle.HIGHEST_PROTOCOL

輸出:4

pickle.DEFAULT_PROTOCOL

輸出:3

pickle模組使用:

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的pickled表示寫入開啟的檔案物件 檔案。

引數:

obj ---- 將obj的pickled表示寫入開啟的檔案物件 檔案。這相當於。Pickler(file, protocol).dump(obj)

protocol ---- 可選的協議引數,一個整數,告訴pickler使用給定的協議; 支援的協議是0到HIGHEST_PROTOCOL。如果未指定,則預設為DEFAULT_PROTOCOL。如果指定了負數,HIGHEST_PROTOCOL則選擇。

file ---- 檔案引數必須具有接受單個位元組的引數寫()write() 方法。因此,它可以是為二進位制寫入開啟的磁碟檔案, io.BytesIO例項或滿足此介面的任何其他自定義物件。

fix_imports ---- 如果fix_imports為true且protocol小於3,則pickle將嘗試將新的Python 3名稱對映到Python 2中使用的舊模組名稱,以便使用Python 2可讀取pickle資料流。

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

將物件的pickle表示作為bytes物件返回,而不是將其寫入檔案。

引數:

引數protocol和fix_imports具有與in中相同的含義 dump()。

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

從開啟的檔案物件 檔案中讀取pickle物件表示,並返回其中指定的重構物件層次結構。這相當於Unpickler(file).load()。pickle的協議版本是自動檢測的,因此不需要協議引數。超過pickle物件的表示的位元組將被忽略。

引數:
  • file ----
    引數檔案必須有兩個方法,一個採用整數引數的read()方法和一個不需要引數readline()方法。兩種方法都應返回位元組。因此,檔案可以是為二進位制讀取開啟的磁碟檔案,io.BytesIO物件或滿足此介面的任何其他自定義物件。

  • 可選的關鍵字引數是fix_imports,encoding和errors,用於控制Python
    2生成的pickle流的相容性支援。如果fix_imports為true,則pickle將嘗試將舊的Python 2名稱對映到Python3中使用的新名稱。編碼和 錯誤告訴pickle如何解碼Python 2醃製的8位字串例項;
    這些預設分別為’ASCII’和’strict’。該編碼可以是“位元組”作為位元組物件讀取這些8位串的例項。

     pickle.loads(bytes_object,*,fix_imports = True,encoding =“ASCII”,errors =“strict” )
    

從bytes物件讀取pickle物件層次結構並返回其中指定的重構物件層次結構。

引數:
  • pickle的協議版本是自動檢測的,因此不需要協議引數。超過pickle物件的表示的位元組將被忽略。
  • 可選的關鍵字引數是fix_imports,encoding和errors,用於控制Python2生成的pickle流的相容性支援。如果fix_imports為true,則pickle將嘗試將舊的Python 2名稱對映到Python3中使用的新名稱。編碼和 錯誤告訴pickle如何解碼Python 2編碼的8位字串例項;這些預設分別為’ASCII’和’strict’。該編碼可以是“位元組”作為位元組物件讀取這些8位串的例項。
兩個類:
pickle.Pickler(file,protocol = None,*,fix_imports = True )

這需要一個二進位制檔案來寫一個pickle資料流。

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

這需要一個二進位制檔案來讀取pickle資料流。
三個異常:
pickle.PickleError
其他序列化異常的通用基類。它繼承了 Exception。
pickle.PicklingError
遇到不可解析的物件時出錯Pickler。它繼承了PickleError。
pickle.UnpicklingError
解開物件時出現問題(例如資料損壞或安全違規)時出錯。它繼承了PickleError。