22.4-序列化和反序列化及pickle

一個人最重要的品質(zhì)镰踏,是懂得克制函筋,克制自己,不是沖動任性奠伪,克制自己的情緒跌帐。

而真正成熟的人,首先應(yīng)該是一個懂得克制自己欲望的人绊率!


總結(jié):

  1. pickle庫是一個很重要的庫谨敛,它的思想在后面很多庫中都有體現(xiàn)的;是一個必須要學(xué)的庫滤否!
  2. py2和py3 pickle協(xié)議可能是不同的脸狸;
  3. 游戲保存:內(nèi)存數(shù)據(jù)的保存(序列化與反序列化), 游戲公司對Python需求比較大顽聂;
  4. 所有語言編程都要考慮序列化與反序列化肥惭,使用pickle來認(rèn)識一下盯仪,json只是在某些方向紊搪,不是所有地方都用,json效率低下;
  5. 在序列化與反序列化中全景,類的屬性方法是共有耀石,不展示,在協(xié)議傳輸時必須一致; 實例 self是千變?nèi)f化的、自己的滞伟,會展示出來揭鳞;

內(nèi)存中的字典、列表梆奈、集合以及各種對象野崇,如何保存在一個文件中?

如何從文件中讀取數(shù)據(jù)亩钟,并讓它們在內(nèi)存中再次恢復(fù)成自己對應(yīng)的類的實例乓梨?
要設(shè)計一套協(xié)議,按照某種規(guī)則清酥,把內(nèi)存中數(shù)據(jù)保存到文件中扶镀。文件是一個字節(jié)序列,所以必須把數(shù)據(jù)轉(zhuǎn)換成字節(jié)焰轻;

序列臭觉,輸出到文件。這就是序列化辱志。反之蝠筑,從文件的字節(jié)序列恢復(fù)到內(nèi)存,就是反序列化揩懒。

序列化

序列化:我們把變量從內(nèi)存中變成可存儲或傳輸?shù)倪^程稱之為序列化菱肖,在Python中叫pickling。序列化之后旭从,就可以把序列化后的內(nèi)容寫入磁盤稳强,或者通過網(wǎng)絡(luò)傳輸?shù)絼e的機(jī)器上。

反序列化:反過來和悦,把變量內(nèi)容從序列化的對象(字節(jié)序列)重新讀到內(nèi)存里稱之為反序列化退疫,即unpickling。

Python提供了pickle模塊來實現(xiàn)序列化鸽素。

相關(guān)模塊

本節(jié)要介紹的就是Python內(nèi)置的幾個用于進(jìn)行數(shù)據(jù)序列化的模塊:

模塊名稱 描述 提供的api
json 用于實現(xiàn)Python數(shù)據(jù)類型與通用(json)字符串之間的轉(zhuǎn)換; 不是所有地方都用褒繁,json效率低下 dumps() 、dump() 馍忽、loads() 棒坏、 load()
pickle 用于實現(xiàn)Python數(shù)據(jù)類型與Python特定二進(jìn)制格式之間的轉(zhuǎn)換;不是一種很高效的協(xié)議序列化傳輸方案 dumps()遭笋、dump()坝冕、loads()、load()瓦呼、
shelve 專門用于將Python數(shù)據(jù)類型的數(shù)據(jù)持久化到磁盤喂窟,shelve是一個類似dict的對象,操作十分便捷 open()

pickle模塊

pickle模塊實現(xiàn)了用于對Python對象結(jié)構(gòu)進(jìn)行 序列化 和 反序列化 的二進(jìn)制協(xié)議,與json模塊不同的是pickle模塊序列化和反序列化的過程分別叫做pickling 和 unpickling:

pickling:是將Python對象轉(zhuǎn)換為字節(jié)流的過程磨澡;
unpickling:是將字節(jié)流二進(jìn)制文件或字節(jié)對象轉(zhuǎn)換回Python對象的過程碗啄;

pickle模塊提供的相關(guān)函數(shù)

pickle模塊提供的幾個序列化/反序列化的函數(shù)與json模塊基本一致:

說明:上面這幾個方法參數(shù)中,*號后面的參數(shù)都是Python 3.x新增的稳摄,目的是為了兼容Python 2.x稚字,具體用法請參看官方文檔。

# 將指定的Python對象通過pickle序列化作為bytes對象返回厦酬,而不是將其寫入文件
dumps(obj, protocol=None, *, fix_imports=True)

# 將通過pickle序列化后得到的字節(jié)對象進(jìn)行反序列化尉共,轉(zhuǎn)換為Python對象并返回
loads(bytes_object, *, fix_imports=True, encoding="ASCII", errors="strict")

# 將指定的Python對象通過pickle序列化后寫入打開的文件對象中,等價于`Pickler(file, protocol).dump(obj)`
dump(obj, file, protocol=None, *, fix_imports=True)

# 從打開的文件對象中讀取pickled對象表現(xiàn)形式并返回通過pickle反序列化后得到的Python對象
load(file, *, fix_imports=True, encoding="ASCII", errors="strict)
# 示例 dump 和 load 方法弃锐;
#內(nèi)建方法袄友;
i = int(99)
s = 'ABC'
l = {'a':0x111111,'b':'abcde','c':[123]}
import pickle

with open('./ser.txt','wb') as f:
    pickle.dump(i,f)  # 對象i ,文件f;
    pickle.dump(s,f)
    pickle.dump(l,f)
#---------------------------------------------------------------------------------------------------------
??Kc.??X?   ABCq .??}q (X?   aq?J??? X?   bq?X?   abcdeq?X?   cq?]q?K{au.

with open('./ser.txt','rb') as f:
    tmp = pickle.load(f)
    print(type(tmp),tmp)
    tmp = pickle.load(f)
    print(type(tmp),tmp)
    tmp = pickle.load(f)
    print(type(tmp),tmp)
#---------------------------------------------------------------------------------------------------------
<class 'int'> 99
<class 'str'> ABC
<class 'dict'> {'a': 1118481, 'b': 'abcde', 'c': [123]}


1.類的屬性方法在序列化中不展示 ,在源代碼中霹菊;
class AA:
    aaaa = 0x111111
    def show(self):
        print('abc')
        
x = AA()
print(x)

with open('./ser.txt','wb') as f:
    pickle.dump(x,f)  # 對象i ,文件f;
with open('./ser.txt','rb') as f:
    a = pickle.load(f)
    print(type(a),hex(a.aaaa))
    a.show()
#------------------------------------------------------------
<__main__.AA object at 0x000002704F7E8E48>
<class '__main__.AA'> 0x111111
abc

2. 序列化與反序列化 兩邊定義的類.方法要一致剧蚣;

#序列化寫入
class AA:
    aaaa = 0x111111
    def show(self):
        print('abc')
        
x = AA()

ser = pickle.dumps(x)
print(ser)

with open('./ser.txt','wb') as f:
    f.write(ser)
    
with open('./ser.txt','rb') as f:
    a = pickle.load(f)
    print(type(a),hex(a.aaaa))
    a.show()
#--------------------------------------------------
b'\x80\x03c__main__\nAA\nq\x00)\x81q\x01.'
<class '__main__.AA'> 0x111111
abc

# 反序列化解讀
class AA:
    aaaa = 60000
    def show(self):
        print('xyz123')
        
with open('./ser.txt','rb') as f:
    a1 = pickle.load(f)
    print((a1.aaaa))
    a1.show()
#--------------------------------------------------
60000
xyz123


3. 類都是公有的,不展示旋廷;每一個self都是一個實例(千變?nèi)f化)鸠按;都是自己的特征,會被序列化饶碘;
class AA:
    bbbb = 222   # 類都是公有的目尖,不展示
    def __init__(self):
        self.aaaa = 0x111111   # 每一個self都是一個實例;都是自己的特征扎运;
        
x = AA()

ser = pickle.dumps(x)
print(ser)

with open('./ser.txt','wb') as f:
    f.write(ser)
#----------------------------------------------------------------------------------------------
b'\x80\x03c__main__\nAA\nq\x00)\x81q\x01}q\x02X\x04\x00\x00\x00aaaaq\x03J\x11\x11\x11\x00sb.'

序列化應(yīng)用——效率問題

一般來說瑟曲,本地序列化的情況,應(yīng)用較少豪治。大多數(shù)場景都應(yīng)用在網(wǎng)絡(luò)傳輸中洞拨。

將數(shù)據(jù)序列化后通過網(wǎng)絡(luò)傳輸?shù)竭h(yuǎn)程節(jié)點,遠(yuǎn)程服務(wù)器上的服務(wù)將接收到的數(shù)據(jù)反序列化后负拟,就可以使用了烦衣。

但是,要注意一點掩浙,遠(yuǎn)程接收端花吟,反序列化時必須有對應(yīng)的數(shù)據(jù)類型,否則就會報錯厨姚。尤其是自定義類衅澈,必須遠(yuǎn)程得有一致的定義。

現(xiàn)在遣蚀,大多數(shù)項目矾麻,都不是單機(jī)的,也不是單服務(wù)的芭梯。需要通過網(wǎng)絡(luò)將數(shù)據(jù)傳送到其他節(jié)點上去险耀,這就需要大量的序列化、反序列化過程玖喘。

但是甩牺,問題是,Python程序之間還可以都是用pickle解決序列化累奈、反序列化贬派,如果是跨平臺、跨語言澎媒、跨協(xié)議pickle就不太適合了搞乏,就需要公共的協(xié)議。例如XML戒努、Json请敦、Protocol Bu?er等,協(xié)議非常多储玫。

不同的協(xié)議侍筛,效率不同、學(xué)習(xí)曲線不同撒穷,適用不同場景匣椰,要根據(jù)不同的情況分析選型。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末端礼,一起剝皮案震驚了整個濱河市禽笑,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蛤奥,老刑警劉巖蒲每,帶你破解...
    沈念sama閱讀 221,273評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異喻括,居然都是意外死亡邀杏,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評論 3 398
  • 文/潘曉璐 我一進(jìn)店門唬血,熙熙樓的掌柜王于貴愁眉苦臉地迎上來望蜡,“玉大人,你說我怎么就攤上這事拷恨〔甭桑” “怎么了?”我有些...
    開封第一講書人閱讀 167,709評論 0 360
  • 文/不壞的土叔 我叫張陵腕侄,是天一觀的道長小泉。 經(jīng)常有香客問我芦疏,道長,這世上最難降的妖魔是什么微姊? 我笑而不...
    開封第一講書人閱讀 59,520評論 1 296
  • 正文 為了忘掉前任酸茴,我火速辦了婚禮,結(jié)果婚禮上兢交,老公的妹妹穿的比我還像新娘薪捍。我一直安慰自己,他們只是感情好配喳,可當(dāng)我...
    茶點故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布酪穿。 她就那樣靜靜地躺著,像睡著了一般晴裹。 火紅的嫁衣襯著肌膚如雪被济。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天涧团,我揣著相機(jī)與錄音溉潭,去河邊找鬼。 笑死少欺,一個胖子當(dāng)著我的面吹牛喳瓣,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播赞别,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼畏陕,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了仿滔?” 一聲冷哼從身側(cè)響起惠毁,我...
    開封第一講書人閱讀 39,660評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎崎页,沒想到半個月后鞠绰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,203評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡飒焦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,287評論 3 340
  • 正文 我和宋清朗相戀三年蜈膨,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片牺荠。...
    茶點故事閱讀 40,427評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡翁巍,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出休雌,到底是詐尸還是另有隱情灶壶,我是刑警寧澤,帶...
    沈念sama閱讀 36,122評論 5 349
  • 正文 年R本政府宣布杈曲,位于F島的核電站驰凛,受9級特大地震影響胸懈,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜恰响,卻給世界環(huán)境...
    茶點故事閱讀 41,801評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望渔隶。 院中可真熱鬧羔挡,春花似錦洁奈、人聲如沸间唉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽呈野。三九已至,卻和暖如春印叁,著一層夾襖步出監(jiān)牢的瞬間被冒,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工轮蜕, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留昨悼,地道東北人。 一個月前我還...
    沈念sama閱讀 48,808評論 3 376
  • 正文 我出身青樓跃洛,卻偏偏與公主長得像率触,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子汇竭,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,440評論 2 359