當我們在內存中定義一個dict的時候,我們是可以隨時修改變量的內容的:
>>> d=dict(name='wc',age=28) >>> d {'name': 'wc', 'age': 28}
我們可以隨時修改name和age的值。但是當我們重新運行程序的時候,name、age的初始化值還是wc和28,實際情況下我們需要保存該dict的最后的值。
我們把變量從內存中變成可存儲或傳輸的過程稱之為序列化。python中稱之為pickling,Java中叫serialization,都是一個意思。序列化之后我們就可以把內容寫入到磁盤或者通過網絡傳輸出去。反之,把變量從序列化的對象重新讀取到內存中稱之為反序列化,洋名叫unpickling。
python中實現序列化的模塊叫pickle。pickle.dumps()方法可以把任意的對象序列化成一個Bytes,然后就可以把這個bytes寫入文件。pickle.dump()方法可以直接把對象序列化寫入一個file-like的對象中。相反的,pickle.loads()方法可以把文件中的內容讀入到一個bytes,然后把這個bytes對象轉換為目標類型對象,也可以使用pickle.load()方法直接從一個file-like對象中直接反序列化出對象:
>>> f = open('E:\\python3.6.3\\workspace\\dump.txt','wb') >>> pickle.dump(d,f) >>> f.close() >>> f=open('E:\\python3.6.3\\workspace\\dump.txt','rb') >>> c = pickle.load(f) >>> c {'name': 'wc', 'age': 28}
JSON
實際開發中我們或多或少都會碰到跨語言傳輸數據的問題,這就要求我們要把對象序列化為標准格式,比如JSON和XML。JSON的表現形式就是一個字符串,可以被所有的語言讀取。可以方便的存儲到磁盤或者通過網絡傳輸。JSON表示的對象是標准的JavaScript的對象,其和python內置的數據類型的對應關系如下:
JSON類型 | Python類型 |
{} | dict |
[] | list |
"" | str |
123.4 | int 或 float |
true/false | True/False |
null | None |
python內置了json模塊可以方便的在python對象和json對象之間轉換:
>>> import json >>> d=dict(name='wc',age=28) >>> json.dumps(d) '{"name": "wc", "age": 28}' >>> c = json.dumps(d) >>> d=json .loads(c) >>> d {'name': 'wc', 'age': 28}
python內置的數據類型可以直接轉換為json類型,但是class對象並不刻意直接轉為json,這是因為class對象默認的並不具有可序列化的屬性。
2種方法,第一種是通過dumps()方法的default參數,把任意一個對象轉換為一個可序列化的對象。下面的例子中,先定義一個Student的class,然后定義一個student2dict()函數,該函數的作用就是把Student的屬性轉換為dict,最后再序列化為json:
>>> import json >>> class Student(object): ... def __init__(self,name,age): ... self.name = name ... self.age = age ... >>> def student2dict(s): ... return {'name':s.name,'age':s.age} ... >>> s=Student('wc',28) >>> print(json.dumps(s,default=student2dict)) {"name": "wc", "age": 28}
第二種方法,借用class對象的__dict__屬性:
>>> class Teacher(object): ... def __init__(self,name,age): ... self.name = name ... self.age = age ... >>> t = Teacher('ly',90) >>> print(json.dumps(t,default=lambda obj:obj.__dict__)) {"name": "ly", "age": 90}