Python3中json的操縱

    在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序列化和反序列化過程當中基本類型和字符串的對應關係:
    
JSON Python
Object dict
Array list
String str
number(int) int
number(real) float
true True
false False
null None
    序列化函數dumps的幾個經常使用參數:
  • separators: 指定生成的json字符串所用的分隔符,兩個分別用於代替「,」、「:」。
  • indent:    用於格式化生成的json字符串,接受整數參數的縮進量。
  • sort_key: true/false,指定dict在序列化時是否按照key排序。
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

  •     default:目的和dumps的default參數同樣。
  •     encode:實現序列化的邏輯部分。
    json.JSONDecoder的方法就是decode    這裏有兩個思路一個是重載Decoder的構造函數設置object_hook,另外一個是重載Decoder的decode方法添加由dict轉換爲自定義類的邏輯。
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)
    使用兩種中的任意一種均可以達到這個目的,不過請注意上述代碼已測試可是省略了一些簡單的非必要代碼,若是有朋友想測試請自行補充:)。
相關文章
相關標籤/搜索