|
上周更新的《Think Python 2e》第14章講述了幾種數(shù)據(jù)持久化的方式,包括dbm、pickle等,但是考慮到篇幅和讀者等因素,并沒有將各種方式都列全。 本文將介紹一個與pickle類似的輕量級數(shù)據(jù)持久化方式,即json。而且json也是在網(wǎng)絡(luò)數(shù)據(jù)傳輸?shù)囊环N常見格式,非常有了解和學(xué)習(xí)的必要。 ? JSON與Pickle的區(qū)別Python官方文檔中是這么比較JSON與Pickle的:
JSON一般使用方式Python中處理json的自帶庫就是json模塊,需要用到的方法大致就是以下4個,其實它們的參數(shù)有很多這里暫且省略。 import json
obj = {'a' : 'b', 'c' : 'd'}
fp = open('obj.json', 'w')
json.dump(obj, fp)
fp.close()s = json.dumps(obj)
x = json.load(open('obj.json', 'r'))
y = json.loads(s)
可以看到,結(jié)尾帶s就是在字符串層面上操作,如果不帶s就是在文件層級操作。obj指的是需要轉(zhuǎn)化的對象,可以是一個字典或者列表,fp是文件句柄,用open打開。s則是一個字符串。 dumps返回的是一個字符串,load和loads則會返回python的對象。 以上是最簡單的一些使用方式,這里還有一些實用的參數(shù)可以選擇。 import json
obj = {u'姓名' : u'無名氏', u'國籍' : u'中國'}
s = json.dumps(obj, ensure_ascii=False, indent=4)
obj2 = json.loads(s, encoding='utf8')
ensure_ascii參數(shù),是在有中文的情況下,設(shè)置為False可以防止將其解碼而得到亂碼,在loads的時候可以指定encoding來保持編碼。 中文編碼問題請參考之前發(fā)的文章:《如何正確解決Python中的中文編碼問題》。 indent參數(shù)如果不指定的話,輸出的字符串就是緊湊的形式,indent指定為4就可以輸出縮進(jìn)為4的美化形式,在需要給人看的時候用這個不錯。 JSON序列化datetime問題Python自己的json.dumps不能序列化datetime對象,如果需要dump這類對象時可以自己定義JSONEncoder。 import json
from datetime import date, datetime
class AdvEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime):
return obj.strftime('%Y-%m-%d %H:%M:%S')
elif isinstance(obj, date):
return obj.strftime('%Y-%m-%d')
else:
return super().default(self, obj)
obj = {}
json.dumps(obj, cls=AdvEncoder)
這樣在dump時指定cls參數(shù)就可以完成序列化datetime的任務(wù)了,如果覺得麻煩的話,可以使用偏函數(shù)的方法自己封裝一下。 import functools adumps = functools.partial(json.dumps, cls=AdvEncoder) d = datetime.now() adumps(d) simplejsonPython中自帶的json庫是在2.6版本中才加入的。因此,如果你需要使用一個更早的Python版本并且處理json數(shù)據(jù),那么你可以安裝一個第三方庫:simplejson。 simplejson模擬了自帶的json庫,目前支持Python 2.5+和Python 3.3+。根據(jù)官方文檔的介紹,該庫在沒有安裝C擴(kuò)展的情況下,速度仍優(yōu)于自帶的json庫。這應(yīng)該也是為什么simplejson在PyPI的下載數(shù)超高的原因之一。 要使用simplejson,你只需要像下面這樣導(dǎo)入即可: import simplejson as json 其他的代碼不需要修改。 參考資料本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或編譯,如需轉(zhuǎn)載,請聯(lián)系微信公眾號“編程派”獲得授權(quán)。轉(zhuǎn)載時,應(yīng)注明來源、作者及原文鏈接。 |
|
|