詳解Python中的序列化與反序列化的使用
學(xué)習(xí)過(guò)marshal模塊用于序列化和反序列化,但marshal的功能比較薄弱,只支持部分內(nèi)置數(shù)據(jù)類型的序列化/反序列化,對(duì)于用戶自定義的類型就無(wú)能為力,同時(shí)marshal不支持自引用(遞歸引用)的對(duì)象的序列化。所以直接使用marshal來(lái)序列化/反序列化可能不是很方便。還好,python標(biāo)準(zhǔn)庫(kù)提供了功能更加強(qiáng)大且更加安全的pickle和cPickle模塊。
cPickle模塊是使用C語(yǔ)言實(shí)現(xiàn)的,所以在運(yùn)行效率上比pickle要高。但是cPickle模塊中定義的類型不能被繼承(其實(shí)大多數(shù)時(shí)候,我們不需要從這些類型中繼承。)。cPickle和pickle的序列化/反序列化規(guī)則是一樣的,我們可以使用pickle序列化一個(gè)對(duì)象,然后使用cPickle來(lái)反序列化。同時(shí),這兩個(gè)模塊在處理自引用類型時(shí)會(huì)變得更加“聰明”,它不會(huì)無(wú)限制的遞歸序列化自引用對(duì)象,對(duì)于同一對(duì)象的多次引用,它只會(huì)序列化一次。例如:
import marshal, pickle list = [1] list.append(list) byt1 = marshal.dumps(list) #出錯(cuò), 無(wú)限制的遞歸序列化 byt2 = pickle.dumps(list) #No problempickle的序列化規(guī)則
Python規(guī)范(Python-specific)提供了pickle的序列化規(guī)則。這就不必?fù)?dān)心不同版本的Python之間序列化兼容性問(wèn)題。默認(rèn)情況下,pickle的序列化是基于文本的,我們可以直接用文本編輯器查看序列化的文本。我們也可以序列成二進(jìn)制格式的數(shù)據(jù),這樣的結(jié)果體積會(huì)更小。更詳細(xì)的內(nèi)容,可以參考Python手冊(cè)pickle模塊。
下面就開(kāi)始使用pickle吧~
pickle.dump(obj, file[, protocol])
序列化對(duì)象,并將結(jié)果數(shù)據(jù)流寫(xiě)入到文件對(duì)象中。參數(shù)protocol是序列化模式,默認(rèn)值為0,表示以文本的形式序列化。protocol的值還可以是1或2,表示以二進(jìn)制的形式序列化。
pickle.load(file)
反序列化對(duì)象。將文件中的數(shù)據(jù)解析為一個(gè)Python對(duì)象。下面通過(guò)一個(gè)簡(jiǎn)單的例子來(lái)演示上面兩個(gè)方法的使用:
#coding=gbk import pickle, StringIO class Person(object): '''自定義類型。 ''' def __init__(self, name, address): self.name = name self.address = address def display(self): print 'name:', self.name, 'address:', self.address jj = Person("JGood", "中國(guó) 杭州") jj.display() file = StringIO.StringIO() pickle.dump(jj, file, 0) #序列化 #print file.getvalue() #打印序列化后的結(jié)果 #del Person #反序列的時(shí)候,必須能找到對(duì)應(yīng)類的定義。否則反序列化操作失敗。 file.seek(0) jj1 = pickle.load(file) #反序列化 jj1.display() file.close()
注意:在反序列化的時(shí)候,必須能找到對(duì)應(yīng)類的定義,否則反序列化將失敗。在上面的例子中,如果取消#del Person的注釋,在運(yùn)行時(shí)將拋AttributeError異常,提示當(dāng)前模塊找不到Person的定義。
pickle.dumps(obj[, protocol])
pickle.loads(string)
我們也可以直接獲取序列化后的數(shù)據(jù)流,或者直接從數(shù)據(jù)流反序列化。方法dumps與loads就完成這樣的功能。dumps返回序列化后的數(shù)據(jù)流,loads返回的序列化生成的對(duì)象。
python模塊中還定義了兩個(gè)類,分別用來(lái)序列化、反序列化對(duì)象。
class pickle.Pickler(file[, protocal]):
該類用于序列化對(duì)象。參數(shù)file是一個(gè)類文件對(duì)象(file-like object),用于保存序列化結(jié)果??蛇x參數(shù)表示序列化模式。它定義了兩個(gè)方法:
dump(obj):
將對(duì)象序列化,并保存到類文件對(duì)象中。參數(shù)obj是要序列化的對(duì)象。
clear_memo()
清空pickler的“備忘”。使用Pickler實(shí)例在序列化對(duì)象的時(shí)候,它會(huì)“記住”已經(jīng)被序列化的對(duì)象引用,所以對(duì)同一對(duì)象多次調(diào)用dump(obj),pickler不會(huì)“傻傻”的去多次序列化。下面是一個(gè)簡(jiǎn)單的例子:
#coding=gbk import pickle, StringIO class Person(object): '''自定義類型。 ''' def __init__(self, name, address): self.name = name self.address = address def display(self): print 'name:', self.name, 'address:', self.address fle = StringIO.StringIO() pick = pickle.Pickler(fle) person = Person("JGood", "Hangzhou China") pick.dump(person) val1 = fle.getvalue() print len(val1) pick.clear_memo() #注釋此句,再看看運(yùn)行結(jié)果 pick.dump(person) #對(duì)同一引用對(duì)象再次進(jìn)行序列化 val2 = fle.getvalue() print len(val2) #---- 結(jié)果 ---- #148 #296 # #將這行代碼注釋掉:pick.clear_memo() #結(jié)果為: #148 #152 class pickle.Unpickler(file):
該類用于反序列化對(duì)象。參數(shù)file是一個(gè)類文件(file-like object)對(duì)象,Unpickler從該參數(shù)中獲取數(shù)據(jù)進(jìn)行反序列化。
load():
反序列化對(duì)象。該方法會(huì)根據(jù)已經(jīng)序列化的數(shù)據(jù)流,自動(dòng)選擇合適的反序列化模式。
#.... 接上個(gè)例子中的代碼 fle.seek(0) unpick = pickle.Unpickler(fle) print unpick.load()
上面介紹了pickle模塊的基本使用,但和marshal一樣,并不是所有的類型都可以通過(guò)pickle序列化的。例如對(duì)于一個(gè)嵌套的類型,使用pickle序列化就失敗。例如:
class A(object): class B(object): def __init__(self, name): self.name = name def __init__(self): print 'init A' b = A.B("my name") print b c = pickle.dumps(b, 0) #失敗哦 print pickle.loads(c)
關(guān)于pickle支持的序列化類型,可以參考Python手冊(cè)。
- Python使用protobuf序列化和反序列化的實(shí)現(xiàn)
- Python使用pickle進(jìn)行序列化和反序列化的示例代碼
- Python 序列化和反序列化庫(kù) MarshMallow 的用法實(shí)例代碼
- Python3.5 Json與pickle實(shí)現(xiàn)數(shù)據(jù)序列化與反序列化操作示例
- Python Json序列化與反序列化的示例
- Python實(shí)現(xiàn)JSON反序列化類對(duì)象的示例
- 老生常談Python序列化和反序列化
- python3序列化與反序列化用法實(shí)例
- Python序列化與反序列化相關(guān)知識(shí)總結(jié)
相關(guān)文章
python進(jìn)階TensorFlow神經(jīng)網(wǎng)絡(luò)擬合線性及非線性函數(shù)
這篇文章是python進(jìn)階學(xué)習(xí)主要介紹了TensorFlow神經(jīng)網(wǎng)絡(luò)擬合線性及非線性函數(shù)原理及示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-10-10Python中字符串相關(guān)操作的運(yùn)算符總結(jié)
這篇文章主要介紹了Python之字符串相關(guān)操作的運(yùn)算符,本文通過(guò)案例給大家詳細(xì)講解python字符串運(yùn)算符的說(shuō)明,需要的朋友可以參考下2023-12-12Jupyter notebook如何實(shí)現(xiàn)打開(kāi)數(shù)據(jù)集
這篇文章主要介紹了Jupyter notebook如何實(shí)現(xiàn)打開(kāi)數(shù)據(jù)集問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01numba CUDA報(bào)錯(cuò)的問(wèn)題解決
本文主要介紹了numba CUDA報(bào)錯(cuò)的問(wèn)題解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02Python模擬鋼琴鍵盤(pán)實(shí)現(xiàn)演奏數(shù)鴨子歌曲
前幾天上課老師給我們講了兩個(gè)模塊,然后利用這兩個(gè)模塊來(lái)模擬鋼琴鍵盤(pán)去簡(jiǎn)單地演奏《數(shù)鴨子》今天來(lái)分享給大家,感興趣的可以了解一下2022-11-11Pandas多級(jí)索引的實(shí)現(xiàn)示例
Pandas 中的多級(jí)索引是一種強(qiáng)大的工具,用于處理具有多個(gè)維度或?qū)哟蔚臄?shù)據(jù),本文主要介紹了Pandas多級(jí)索引的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下2024-01-01