【Python之旅】第三篇(二):Pickle序列化

說明:關於Pickle的說明

    作如下說明:

序列化的概念很簡單。內存裏面有一個數據結構,你希望將它保存下來,重用,或者發送給其他人。你會怎麼做?嗯, 這取決於你想要怎麼保存,怎麼重用,發送給誰。很多遊戲允許你在退出的時候保存進度,然後你再次啓動的時候回到上次退出的地方。(實際上, 很多非遊戲程序也會這麼幹。) 在這個情況下, 一個捕獲了當前進度的數據結構需要在你退出的時候保存到磁盤上,接着在你重新啓動的時候從磁盤上加載進來。

什麼東西能用pickle模塊存儲?
–所有Python支持的 原生類型 : 布爾, 整數, 浮點數, 複數, 字符串, bytes(字節串)對象, 字節數組, 以及 None.
–由任何原生類型組成的列表,元組,字典
–由任何原生類型組成的列表,元組,字典和集合組成的列表,元組,字典和集合(可以一直嵌套下去,直至Python支持的最大遞歸層數).
–函數,類,和類的實例(帶警告)。




1.Pickle的簡單介紹與使用


·簡單說明如下:

a.字典的數據結構在內存中存儲,保存爲文件無法識別,如果要保存,並在下一次打開時還能用,需要做Pickle序列化存儲;

b.讀取時需要反序列化;

c.pickle可以把程序的執行進度都保存下來;


·給出實例1:Pickle只保存一種狀態

a.存儲序列化

#!/usr/bin/env python

import pickle
account_info = {
'8906143632':['alex3714', 15000, 15000],
'8908223631':['rachel', 9000,9000]
}

f=file('account.pkl','wb')
pickle.dump(account_info,f)
f.close()

b.讀取序列化

#!/usr/bin/env python

import pickle

pkl_file = file('account.pkl','rb')
account_list = pickle.load(pkl_file)
pkl_file.close()

print account_list

c.執行結果如下:

xpleaf@xpleaf-machine:/mnt/hgfs/Python/day3$ python pickle_w.py 
xpleaf@xpleaf-machine:/mnt/hgfs/Python/day3$ python pickle_r.py 
{'8908223631': ['rachel', 9000, 9000], '8906143632': ['alex3714', 15000, 15000]}

d.生成的account.pkl中保存了字典的狀態:

xpleaf@xpleaf-machine:/mnt/hgfs/Python/day3$ cat account.pkl 
(dp0
S'8908223631'
p1
(lp2
S'rachel'
p3
aI9000
aI9000
asS'8906143632'
p4
(lp5
S'alex3714'
p6
aI15000
aI15000
as.


·實例2:Pickle保存多種狀態

a.存儲序列化代碼修改爲如下:

#!/usr/bin/env python

import pickle
account_info = {
'8906143632':['alex3714', 15000, 15000],
'8908223631':['rachel', 9000,9000]
}

f=file('account.pkl','wb')
pickle.dump(account_info,f)    #第一次狀態保存
account_info['8908223631'][0] = 'xpleaf'    #修改字典中的某項內容
pickle.dump(account_info,f)    #第二次狀態保存
f.close()

b.執行存儲序列化程序,使兩次狀態保存到文件中:

xpleaf@xpleaf-machine:/mnt/hgfs/Python/day3$ python pickle_w.py 
xpleaf@xpleaf-machine:/mnt/hgfs/Python/day3$ cat account.pkl 
(dp0
S'8908223631'
p1
(lp2
S'rachel'
p3
aI9000
aI9000
asS'8906143632'
p4
(lp5
S'alex3714'
p6
aI15000
aI15000
as.(dp0
S'8908223631'
p1
(lp2
S'xpleaf'    #對比只保存一次狀態的情況,這裏多了修改的內容'xpleaf'
p3
aI9000
aI9000
asS'8906143632'
p4
(lp5
S'alex3714'
p6
aI15000
aI15000
as.

c.在交互器中測試:

>>> import pickle
>>> f = file('account.pkl')
>>> acc1 = pickle.load(f)    #反序列化讀取第一次狀態的內容
>>> acc2 = pickle.load(f)    #反序列化讀取第二次狀態的內容
>>> acc3 = pickle.load(f)    #無第三次狀態內容,讀取失敗
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/pickle.py", line 1378, in load
    return Unpickler(file).load()
  File "/usr/lib/python2.7/pickle.py", line 858, in load
    dispatch[key](self)
  File "/usr/lib/python2.7/pickle.py", line 880, in load_eof
    raise EOFError
EOFError
>>> acc1
{'8908223631': ['rachel', 9000, 9000], '8906143632': ['alex3714', 15000, 15000]}
>>> acc2
{'8908223631': ['xpleaf', 9000, 9000], '8906143632': ['alex3714', 15000, 15000]}

·可在一個文件中保存多個狀態(dump),但是得一個一個地調取狀態(load),不建議這樣做;




2.Pickle的其它說明與使用


·序列化使得不同程序之間可以交互數據的讀取;

·Pickle中的dump()只能將數據結構的序列化存儲在磁盤中,然後load()再通過反序列化調用磁盤的相關文件;

·使用Pickle的dumps()與loads()則可以直接在內存中操作:

>>> acc1
{'8908223631': ['rachel', 9000, 9000], '8906143632': ['alex3714', 15000, 15000]}
>>> pickle.dumps(acc1)
"(dp0\nS'8908223631'\np1\n(lp2\nS'rachel'\np3\naI9000\naI9000\nasS'8906143632'\np4\n(lp5\nS'alex3714'\np6\naI15000\naI15000\nas."
>>> c = pickle.dumps(acc1)
>>> pickle.loads(c)
{'8908223631': ['rachel', 9000, 9000], '8906143632': ['alex3714', 15000, 15000]}

·只需提供操作接口即可實現動態地交互程序的狀態(遊戲進度切換的例子,P1--P2,P1實時將遊戲進度交給P2);

·與Pickle有同樣重要的是json,用法與Pickle類似;

·序列化的思想對於不同平臺和不同編程語言的數據結構交互有着重要的作用,由於未深入學習,這裏不作說明。





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章