Python學習 IO程式設計

2021-07-05 07:20:06 字數 2486 閱讀 6794

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 ...