python基礎模塊之序列化
---什麽是序列化(picking)?
我們把變量從內存中變成可存儲或傳輸的過程稱之為序列化。
序列化之後,就可以把序列化後的內容寫入磁盤,或者通過網絡傳輸到別的機器上。
反過來,把變量內容從序列化的對象重新讀到內存裏稱之為反序列化,即unpickling。
舉例:大家應該都玩過魔獸爭霸,應該知道該遊戲有一個存檔的功能,我每次不想玩得時候就可以存檔,然後再玩得時候我們根本不需要重新開始玩,只需要讀檔就可以了。我們現在學習的事面向對象的思想,那麽在我們眼中不管是我們的遊戲角色還是遊戲中的怪物、裝備等等都可以看成是 一個個的對象,進行簡單的分析。
角色對象(包含等級、性別、經驗值、HP、MP等等屬性)武器對象(包含武器的類型、武器的傷害、武器附加的能力值等等屬性)
怪物對象(包含等級、經驗值、攻擊、怪物類型等等)
於是玩遊戲過程變的非常有意思了,創建遊戲角色就好像是創建了一個角色對象,拿到武器就好像創建了一個武器對象,遇到的怪物、NPC等等都是對象了。
然後再用學 過的知識進行分析,我們發現對象的數據都是保存在內存中的,應該都知道內存的數據在斷電以後是會消失的,但是我們的遊戲經過存檔以後,就算你關機了幾天, 再進入遊戲的時候,讀取你的存檔發現你在遊戲中的一切都還在呢,奇怪了,明明內存中的數據已經沒有了啊,這是為什麽呢?於是再仔細考慮,電腦中有硬盤這個 東西在斷電以後保存的數據是不會丟的(要是由於斷電導致的硬盤損壞了,沒有數據了,哈哈,不在此考慮中)。那麽應該很容易的想到這些數據是被保存在硬盤中 了。沒錯!這就是對象的持久化,也就是我們今天要講的對象的序列化。那麽反序列化就很好理解了就是將存放在硬盤中的信息再讀取出來形成對象。
---如何序列化?
在python中提供了兩個模塊可進行序列化。分別是pickle和json。
pickle
pickle是python中獨有的序列化模塊,所謂獨有,就是指不能和其他編程語言的序列化進行交互,因為pickle將數據對象轉化為bytes
>>> 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則是反序列化。
dumps
dumps將所傳入的變量的值序列化為一個bytes,然後,就可以將這個bytes寫入磁盤或者進行傳輸。
而dump則更加一步到位,在dump中可以傳入兩個參數,一個為需要序列化的變量,另一個為需要寫入的文件。
dumploads當我們要把對象從磁盤讀到內存時,可以先把內容讀到一個bytes,然後用loads方法反序列化出對象,也可以直接用load方法直接反序列化一個文件。
loads loadjson
如果我們要在不同的編程語言之間傳遞對象,就必須把對象序列化為標準格式,比如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‘}
python基礎模塊之序列化