在python中提供了標準庫json將基本類型的數據轉化成json格式,可是在涉及到自定義類型時須要擴展或者複寫Encoder(Decoder)來實現,默認狀況下json會拋出"TypeErro: xxx is not json serializable"的錯誤。本文參考了文章Json概述以及python對json的相關操做。
html
對於基本類型的數據直接使用json.dumps和json.loads方法進行序列化和反序列化。 python
import json array = ['d', 'b', 'c', 'a', {'b':100, 'a':'letter a'}] encodestr = json.dumps(array) org_obj = json.loads(encodestr)
JSON | Python |
Object | dict |
Array | list |
String | str |
number(int) | int |
number(real) | float |
true | True |
false | False |
null | None |
json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4, separators=(',', ': '))
json.dumps函數接受參數default用於指定一個函數,該函數可以把自定義類型的對象轉換成可序列化的基本類型。json.loads函數接受參數objecthook用於指定函數,該函數負責吧反序列化後的基本類型對象轉換成自定義類型的對象。 json
boy1 = boy('Will', 20) #default method for decode def boydefault(obj): if isinstance(obj, boy): return {'name': obj.name, 'age': obj.age} return obj; def boyhook(dic): print('test') if dic['name']: return boy(dic['name'], dic['age']) return dic boy_encode_str = json.dumps(boy1, default=boydefault) new_boy = json.loads(boy_encode_str, object_hook=boyhook) print(boy_encode_str) print(new_boy)
除此之外json庫提供了JSONEncoder和JSONDecoder兩個類用於json的序列化和反序列化,能夠經過子類實現自定義類的json操做(估計json庫內部邏輯也是用的這兩個類)。
json.JSONEncoder的主要方法: ide
class BoyEncoder(json.JSONEncoder): def default(self, o): if isinstance(o, boy): return {'name': o.name, 'age': o.age} return json.JSONEncoder.default(o); #override decode method class BoyDecoder(json.JSONDecoder): def decode(self, s): dic = super().decode(s); return boy(dic['name'], dic['age']); #override __init__ method class BoyDecoder2(json.JSONDecoder): def __init__(self): json.JSONDecoder.__init__(self) self.object_hook = boyhook boy_encode_str = json.dumps(boy1, cls=BoyEncoder) new_boy = json.loads(boy_encode_str, cls=BoyDecoder) new_boy2 = json.loads(boy_encode_str, cls=BoyDecoder2) print(boy_encode_str) print(new_boy) print(new_boy2)使用兩種中的任意一種均可以達到這個目的,不過請注意上述代碼已測試可是省略了一些簡單的非必要代碼,若是有朋友想測試請自行補充:)。