not JSON serializable解决方法

问题描述:

Python内置的json模块提供了非常完善的Python对象到JSON格式的转换。

json.dumps()  # 将Python中的对象转换为JSON中的字符串对象
json.loads()  # 将JSON中的字符串对象转换为Python中的对象

这个问题是由于json.dumps()函数引起的。 dumps是将dict数据转化为str数据,但是dict数据中包含byte、int、float、datetime等等的时候,数据会报错。

可能会遇到TypeError: Object of type xxx is not JSON serializable错误,也就是无法序列化某些对象格式。

注意:json默认支持的类型只有下面几种,其他的类型,比如自定义的类或者date类型,都需要自定义jsonEncoder。

    Supports the following objects and types by default:
 
    +-------------------+---------------+
    | Python            | JSON          |
    +===================+===============+
    | dict              | object        |
    +-------------------+---------------+
    | list, tuple       | array         |
    +-------------------+---------------+
    | str               | string        |
    +-------------------+---------------+
    | int, float        | number        |
    +-------------------+---------------+
    | True              | true          |
    +-------------------+---------------+
    | False             | false         |
    +-------------------+---------------+
    | None              | null          |
    +-------------------+---------------+

解决办法:

默认的编码函数很多数据类型都不能编码,自定义序列化,因此可以自己写一个Myencoder去继承json.JSONEncoder,具体如下:

1.MyEncoder.py

import json
class MyEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime.datetime):
            print("MyEncoder-datetime.datetime")
            return obj.strftime("%Y-%m-%d %H:%M:%S")
        if isinstance(obj, bytes):
            return str(obj, encoding='utf-8')
        if isinstance(obj, int):
            return int(obj)
        elif isinstance(obj, float):
            return float(obj)
        #elif isinstance(obj, array):
        #    return obj.tolist()
        else:
            return super(MyEncoder, self).default(obj)

2.调用封装的模块来转换字符串

from MyEncoder import MyEncoder
json.dumps(data,cls=MyEncoder,indent=4)

拓展:numpy转json

# NpEncoder
import json
import numpy as np
class NpEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, np.integer):
            return int(obj)
        elif isinstance(obj, np.floating):
            return float(obj)
        elif isinstance(obj, np.ndarray):
            return obj.tolist()
        else:
            return super(NpEncoder, self).default(obj)
data = {...}
data = json.dumps(data, cls=NpEncoder, indent=4, ensure_ascii=False))
posted @ 2022-12-14 09:46  阿木古冷  阅读(4094)  评论(0编辑  收藏  举报