python-json的自定義編碼器與自定義解碼器
json的數據類型有限,在實際業務中可能會遇到數據無法使用JSON編碼的問題。如果我們需要轉發的數據有大量或位置不規則的json無法解析數據類型時,事先處理就變成了一件比較麻煩的事。這里可以使用json模塊的編碼器和解碼器來解決這個問題。
自定義編碼器
import json
from decimal import Decimal
from datetime import datetime
# json擴展編碼器
class MyJsonEncoder(json.JSONEncoder):
def default(self, field):
"""
:param field: 原始的數據
:return: 處理后的數據
"""
if isinstance(field, datetime):
return field.strftime('%Y-%m-%d %H:%M:%S')
elif isinstance(field, Decimal):
return str(field)
else:
return json.JSONEncoder.default(self, field)
info = [Decimal("1"), datetime.now(), {"decimal": Decimal("2"), "datetime": datetime.now()}]
print(json.dumps(info, cls=MyJsonEncoder)) # cls -> 指定JSON編碼器
==>
["1", "2023-02-03 16:48:29", {"decimal": "2", "datetime": "2023-02-03 16:48:29"}]
自定義解碼器
# json自定義解碼器
class MyJsonDecoder(json.JSONDecoder):
def __init__(self, *args, **kwargs):
super().__init__(
object_hook=self.object_hook,
parse_float=self.parse_float,
parse_int=self.parse_int,
parse_constant=self.parse_constant,
# object_pairs_hook=self.object_pairs_hook,
*args, **kwargs)
def object_hook(self, o):
"""
對字典解碼,如果同時設置'object_pairs_hook','object_hook'將不生效
:param o: 原始數據字典
:return: 實際需要的數據
"""
return o
def parse_float(self, o):
"""
對浮點型解碼
:param o: 原始浮點型
:return: 實際需要的數據
"""
return o
def parse_int(self, o):
"""
對整型解碼
:param o: 原始整型
:return: 實際需要的數據
"""
return o
def parse_constant(self, o):
"""
對于'-Infinity', 'Infinity', 'NaN'之類的特殊值進行解碼
:param o:
:return:
"""
return o
def object_pairs_hook(self, o):
"""
對有序列表解碼,如果同時設置'object_hook','object_hook'將不生效
:param o: 原始數據數據
:return: 實際需要的數據
"""
return o
info = '[1, "2023-02-03 16:48:29", {"decimal": "2.2", "datetime": "2023-02-03 16:48:29"}, [3, "4"]]'
print(json.loads(info, cls=MyJsonDecoder))
==>
['1', '2023-02-03 16:48:29', {'decimal': '2.2', 'datetime': '2023-02-03 16:48:29'}, ['3', '4']]
實際舉例-支持decimal格式數據
import json
from decimal import Decimal
# json自定義編碼器
class MyJsonEncoder(json.JSONEncoder):
def default(self, field):
if isinstance(field, Decimal):
return {"__class__": "Decimal", "value": str(field)}
else:
return json.JSONEncoder.default(self, field)
# json自定義解碼器
class MyJsonDecoder(json.JSONDecoder):
def __init__(self, *args, **kwargs):
super().__init__(object_hook=self.object_hook, *args, **kwargs)
def object_hook(self, o):
if o.get('__class__') == "Decimal":
return Decimal(o.get('value', 0))
return o
info = [Decimal("1"), Decimal("1.1"),
{"decimal1": Decimal("2.1"), "decimal2": Decimal("2.2")},
[Decimal("3.1"), Decimal("3.2")]]
info1 = json.dumps(info, cls=MyJsonEncoder)
info2 = json.loads(info1, cls=MyJsonDecoder)
print(info1, end="\n\n")
print(info2)
==>
[{"__class__": "Decimal", "value": "1"}, {"__class__": "Decimal", "value": "1.1"}, {"decimal1": {"__class__": "Decimal", "value": "2.1"}, "decimal2": {"__class__": "Decimal", "value": "2.2"}}, [{"__class__": "Decimal", "value": "3.1"}, {"__class__": "Decimal", "value": "3.2"}]]
[Decimal('1'), Decimal('1.1'), {'decimal1': Decimal('2.1'), 'decimal2': Decimal('2.2')}, [Decimal('3.1'), Decimal('3.2')]]

浙公網安備 33010602011771號