pickle和cPickle:Python物件的序列化(上)

發表於2016-07-21

目的:Python物件序列化

可用性:pickle至少1.4版本,cPickle 1.5版本以上


pickle模組實現了一種演算法,將任意一個Python物件轉化成一系列位元組(byets)。此過程也呼叫了serializing物件。代表物件的位元組流之後可以被傳輸或儲存,再重構後建立一個擁有相同特徵(the same characteristics)的新的物件。

cPickle使用C而不是Python,實現了相同的演算法。這比Python實現要快好幾倍,但是它不允許使用者從Pickle派生子類。如果子類對你的使用來說無關緊要,那麼cPickle是個更好的選擇。

警告:本文件直接說明,pickle不提供安全保證。如果你在多執行緒通訊(inter-process communication)或者資料儲存或儲存資料中使用pickle,一定要小心。請勿信任你不能確定為安全的資料。

匯入

如平常一樣,嘗試匯入cPickle,給它賦予一個別名“pickle”。如果因為某些原因匯入失敗,退而求其次到Python的原生(native)實現pickle模組。如果cPickle可用,能給你提供一個更快速的執行,否則只能是輕便的執行(the portable implementation)。

編碼和解碼

第一個例子將一種資料結構編碼成一個字串,然後把該字串列印至控制檯。使用一種包含所有原生型別(native types)的資料結構。任何型別的例項都可被醃漬(pickled,譯者注:模組名稱pickle的中文含義為醃菜),在稍後的例子中會演示。使用pickle.dumps()來建立一個表示該物件值的字串。

pickle預設僅由ASCII字元組成。也可以使用更高效的二進位制格式(binary format),只是因為在列印的時候更易於理解,本頁的所有例子都使用ASCII輸出。

資料被序列化以後,你可以將它們寫入檔案、套接字、管道等等中。之後你也可以從檔案中讀取出來、將它反醃漬(unpickled)而構造一個具有相同值得新物件。

如你所見,這個新構造的物件與原物件相同,但並非同一物件。這不足為奇。

與流一起工作

dumps()loads()外,pickle還提供一對用在類檔案流(file-like streams)的轉化函式。可以往一個流中寫對個物件,然後從流中把它們讀取出來,此過程不需要預先寫入的物件有幾個、它們多大。

這個例子使用SringIO快取器(buffer)模擬流,所以在建立可讀流的時候我們玩了一把。一個簡單資料庫的格式化也可以使用pickles來儲存物件,只是shelve與之工作更加簡便。

除了儲存資料,pickles在程式間通訊(inter-process communication)中也非常稱手。例如,使用os.fork()os.pipe()可以創立工作者程式(worker processes),從一個管道(pipe)讀取作業指令(job instruction)然後將結果寫入另一個管道。管理工作者池(worker pool)和將作業送入、接受響應(response)的核心程式碼可被重用,因為作業和響應並不屬於某個特定類中。如果你使用管道或者套接字(sockets),在通過連至另一端(end)的連線傾倒(dumps)所有物件、推送資料之後,別忘了沖洗(flush)。如果你想寫自己的工作者池管理器,請看multiprocessing

Next–>

相關文章