首页 > 编程语言 >python-json的自定义编码器与自定义解码器

python-json的自定义编码器与自定义解码器

时间:2023-02-03 18:14:27浏览次数:35  
标签:__ return 自定义 python Decimal hook json 解码器 self

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')]]

标签:__,return,自定义,python,Decimal,hook,json,解码器,self
From: https://www.cnblogs.com/shof/p/17090121.html

相关文章

  • 【Azure Cache for Redis】Python Djange-Redis连接Azure Redis服务遇上(104, 'Connec
    问题描述使用Python连接AzureRedis服务,因为在代码中使用的是Djange-redis组件,所以通过如下的配置连接到AzureRedis服务:CACHES={"default":{"BACKEND":"dj......
  • Python 异步: 什么是事件循环 ?(6)
    asyncio程序的核心是事件循环。在本节中,我们将花点时间看一下asyncio事件循环。1.什么是Asyncio事件循环事件循环是用于在单个线程中执行协程的环境。事件循环是异......
  • Python---- 一闭三器
    一闭三器闭包装饰器迭代器生成器闭包保证数据安全闭包结构内层函数对外层函数的局部变量的使用,内层函数被称为闭包函数闭指的是:该函数的内部函数包......
  • 基于python的小翻译工具
    这里的翻译接口是基于百度翻译的API这里的方案是利用百度翻译开放平台实现的会稍微麻烦点,但是更加方便个性化翻译也可以通过爬虫的形式,直接操作百度翻译网页来实现前......
  • [oeasy]python0072_修改字体前景颜色_foreground_color_font
    修改颜色回忆上次内容m可以改变字体样式0-9之间设置的都是字体效果0重置为默认1变亮2变暗3斜体4下划线5慢闪6快闪7前景背景互换8隐藏9中划......
  • python Counter
    fromcollectionsimportCounterL1='iuasdhfiuhaefi'L2=[1,2,3,4,5,6,6,6,7,7,8,8,8,11,2,1]L3={1:2,3:4,5:6}L4={1,2,23,4,5,6,76,7}print(Counter(L1))......
  • 【工具】-Misc-Python-dsstore
    介绍这是一个.DS_Store解析工具。什么是.DS_Store.DS_Store是DesktopServicesStore的缩写,是macOS操作系统上的一个不可见文件,只要您使用“Finder”查看文件夹,它......
  • #Python 文本包含pandas的 Series.str.contains函数
    一:基础的函数组成’’‘Series.str.contains(pat,case=True,flags=0,na=nan,regex=True)’’'测试pattern或regex是否包含在Series或Index的字符串中。返回布尔值系列......
  • Python算术运算符
    Python算术运算符以下假设变量: a=10,b=20:运算符描述实例+加-两个对象相加a+b输出结果30-减-得到负数或是一个数减去另一个数a-b输出结果-10*乘-两个数相乘或......
  • KingbaseES 支持自定义异常
    KingbaseESPLSQL从V8R6C4版本开始,支持用户自定义异常。具体例子如下:createorreplaceprocedurep_test()aserror_numberEXCEPTION;xinteger:=1;begin......