python基礎之模塊之序列化

---什麼是序列化(picking)?html

 咱們把變量從內存中變成可存儲或傳輸的過程稱之爲序列化python

 序列化以後,就能夠把序列化後的內容寫入磁盤,或者經過網絡傳輸到別的機器上。編程

 反過來,把變量內容從序列化的對象從新讀到內存裏稱之爲反序列化,即unpickling。json

 舉例:你們應該都玩過魔獸爭霸,應該知道該遊戲有一個存檔的功能,我每次不想玩得時候就能夠存檔,而後再玩得時候咱們根本不須要從新開始玩,只須要讀檔就能夠了。咱們如今學習的事面向對象的思想,那麼在咱們眼中不論是咱們的遊戲角色仍是遊戲中的怪物、裝備等等均可以當作是 一個個的對象,進行簡單的分析。網絡

角色對象(包含等級、性別、經驗值、HPMP等等屬性)
武器對象(包含武器的類型、武器的傷害、武器附加的能力值等等屬性)
怪物對象(包含等級、經驗值、攻擊、怪物類型等等)
因而玩遊戲過程變的很是有意思了,建立遊戲角色就好像是建立了一個角色對象,拿到武器就好像建立了一個武器對象,遇到的怪物、NPC等等都是對象了。
而後再用學 過的知識進行分析,咱們發現對象的數據都是保存在內存中的,應該都知道內存的數據在斷電之後是會消失的,可是咱們的遊戲通過存檔之後,就算你關機了幾天, 再進入遊戲的時候,讀取你的存檔發現你在遊戲中的一切都還在呢,奇怪了,明明內存中的數據已經沒有了啊,這是爲何呢?因而再仔細考慮,電腦中有硬盤這個 東西在斷電之後保存的數據是不會丟的(要是因爲斷電致使的硬盤損壞了,沒有數據了,哈哈,不在此考慮中)。那麼應該很容易的想到這些數據是被保存在硬盤中 了。沒錯!這就是對象的持久化,也就是咱們今天要講的對象的序列化。那麼反序列化就很好理解了就是將存放在硬盤中的信息再讀取出來造成對象。

 

---如何序列化?編程語言

  在python中提供了兩個模塊可進行序列化。分別是pickle和json。ide

pickle函數

  pickle是python中獨有的序列化模塊,所謂獨有,就是指不能和其餘編程語言的序列化進行交互,由於pickle將數據對象轉化爲bytes
post

 

>>> import pickle
>>> d=[1,2,3,4]
>>> pickle.dumps(d)
b'\x80\x03]q\x00(K\x01K\x02K\x03K\x04e.'
>>> type(pickle.dumps(d))
<class 'bytes'>     #類型爲bytes

 

  pickle模塊提供了四個功能:dumps、dump、loads、load。學習

  dumps和dump都是進行序列化,而loads和load則是反序列化。

 

>>> import pickle
>>> d=[1,2,3,4]
>>> pickle.dumps(d)
b'\x80\x03]q\x00(K\x01K\x02K\x03K\x04e.'
dumps

  dumps將所傳入的變量的值序列化爲一個bytes,而後,就能夠將這個bytes寫入磁盤或者進行傳輸。

  而dump則更加一步到位,在dump中能夠傳入兩個參數,一個爲須要序列化的變量,另外一個爲須要寫入的文件。

f=open('file_test','wb')
>>> d=[1,2,3,4]
>>> pickle.dump(d,f)
>>> f.close()
>>> f=opem('file_test','rb')
 f=open('file_test','rb')
>>> f.read()
b'\x80\x03]q\x00(K\x01K\x02K\x03K\x04e.'
dump

  loads當咱們要把對象從磁盤讀到內存時,能夠先把內容讀到一個bytes,而後用loads方法反序列化出對象,也能夠直接用load方法直接反序列化一個文件。

>>> d=[1,2,3,4]
>>> r=pickle.dumps(d)
>>> print(r)
b'\x80\x03]q\x00(K\x01K\x02K\x03K\x04e.'
>>> pickle.loads(r)
[1, 2, 3, 4]
loads
>>> d=[1,2,3,4]
>>> f=open('file_test','wb')
>>> pickle.dump(d,f)
>>> f.close()
>>> f=open('file_test','rb')
>>> r=pickle.load(f)
>>> f.close()
>>> print(r)
[1, 2, 3, 4]
load

json

  若是咱們要在不一樣的編程語言之間傳遞對象,就必須把對象序列化爲標準格式,好比XML,但更好的方法是序列化爲JSON,由於JSON表示出來就是一個字符串,能夠被全部語言讀取,也能夠方便地存儲到磁盤或者經過網絡傳輸。JSON不只是標準格式,而且比XML更快,並且能夠直接在Web頁面中讀取,很是方便。

  若是想要詳細瞭解JSON的話,推薦一篇博文:http://www.cnblogs.com/mcgrady/archive/2013/06/08/3127781.html

  json中的方法和pickle中差很少,也是dumps,dump,loads,load。使用上也沒有什麼區別,區別在於,json中的序列化後格式爲字符。

>>> import json
>>> d=[1,2,3,4]
>>> json.dumps(d)
'[1, 2, 3, 4]'
>>> type(json.dumps(d))
<class 'str'>           #類型爲str

由於python中一切事物皆對象,全部對象都是基於類建立的,因此,‘類’在python中佔據了至關大的比重。咱們可否將類的實例進行序列化呢?

>>> class student(object):
...     def __init__(self,name,age,course):
...         self.name=name
...         self.age=age
...         self.course=course
...         
>>> a=student('linghuchong',24,'xixingdafa')
>>> import json
>>> json.dumps(a)
TypeError: <student object at 0x035B8230> is not JSON serializable

 暈,居然不能!如今幾乎都是面向對象編程,類這麼重要,居然不能序列化,怎麼搞?

不要着急,前面的代碼之因此沒法把student類實例序列化爲JSON,是由於默認狀況下,dumps方法不知道如何將student實例變爲一個JSON的'{}'對象。

咱們須要’告訴‘json模塊如何轉換。

>>> def st_to_dict(a):
...     return {'name':a.name,'age':a.age,'course':a.course}
...     
>>> print(json.dumps(a,default=st_to_dict))          #default參數就是告知json如何進行序列化
{"course": "xixingdafa", "name": "linghuchong", "age": 24}
    

固然,若是咱們每定義一個類,還得再定義一下這個類的實例轉換爲字典的函數實在是太麻煩了!!咱們有一個一勞永逸的辦法。

print(json.dumps(a, default=lambda obj: obj.__dict__))

其中的__dict__不需咱們在類中定義,由於一般class的實例都有一個__dict__屬性,它就是一個字典,用來存儲實例變量。

>>> print(a.__dict__)
{'course': 'xixingdafa', 'age': 24, 'name': 'linghuchong'}
相關文章
相關標籤/搜索