json高階
python的dict
物件可以直接序列化為json的{}
,不過,很多時候,我們更喜歡用class
表示物件,比如定義member
類,然後序列化:
import json
class
member
(object):
def__init__
(self, name, age, score):
self.name = name
self.age = age
self.score = score
m = member('james', 24, 80)
print(json.dumps(m))
執行**,出現錯誤typeerror
:
traceback (most recent call
last):
...typeerror: <__main__.member object at
0x10603cc50> is
not json serializable
錯誤的原因是member
物件不是乙個可序列化為json的物件。
如果連class
的例項物件都無法序列化為json,這肯定不合理!
我們仔細看看dumps()
方法的引數列表,可以發現,除了第乙個必須的obj
引數外,dumps()
方法還提供了一大堆的可選引數:
這些可選引數就是讓我們來定製json序列化。前面的**之所以無法把member
類例項序列化為json,是因為預設情況下,dumps()
方法不知道如何將member
例項變為乙個json的{}
物件。
可選引數default
就是把任意乙個物件變成乙個可序列為json的物件,我們只需要為member
專門寫乙個轉換函式,再把函式傳進去即可:
def
member2dict
(mem):
return
這樣,member
例項首先被member2dict()
函式轉換成dict
,然後再被順利序列化為json:
>>> print(json.dumps(s, default=member2dict))
不過,下次如果遇到乙個worker
類的例項,照樣無法序列化為json。我們可以偷個懶,把任意class
的例項變為dict
:
print(json.dumps(s, default=lambda obj: obj.__dict__))
因為通常class
的例項都有乙個__dict__
屬性,它就是乙個dict
,用來儲存例項變數。也有少數例外,比如定義了__slots__
的class。
同樣的道理,如果我們要把json反序列化為乙個member
物件例項,loads()
方法首先轉換出乙個dict
物件,然後,我們傳入的object_hook
函式負責把dict
轉換為student
例項:
def
dict2member
(d):
return member(d['name'], d['age'], d['score'])
執行結果如下:
>>> json_str = ''
>>> print(json.loads(json_str, object_hook=dict2member))
<__main__.membert
object
at0x10cd3c190>
列印出的是反序列化的member
例項物件。
(1)python語言特定的序列化模組是pickle
,但如果要把序列化搞得更通用、更符合web標準,就可以使用json
模組。
(2)json
模組的dumps()
和loads()
函式是定義得非常好的介面的典範。當我們使用時,只需要傳入乙個必須的引數。但是,當預設的序列化或反序列機制不滿足我們的要求時,我們又可以傳入更多的引數來定製序列化或反序列化的規則,既做到了介面簡單易用,又做到了充分的擴充套件性和靈活性。
python學習 I O程式設計
1 輸入資料 input 輸出資料 print name input print name name print name s name for i in range 1,10 print i for i in range 1,10 name input print name name print ...
python學習筆記 IO程式設計
由於cpu和記憶體的速度遠遠高於外設的速度,所以,在io程式設計中,就存在速度嚴重不匹配的問題。舉個例子來說,比如要把100m的資料寫入磁碟,cpu輸出100m的資料只需要0.01秒,可是磁碟要接收這100m資料可能需要10秒,怎麼辦呢?有兩種辦法 第一種是cpu等著,也就是程式暫停執行後續 等10...
python學習筆記 九 IO程式設計
一.檔案讀寫 1.讀檔案 try f open d 1.txt r 讀取普通檔案 f open d 1.jpg rb 讀取二進位制檔案 f.read finally if f f.close with open d 1.txt r as f 使用with會自動呼叫close for line in ...