TypeError:X 类型的对象不是 JSON 可序列化的

Posted

技术标签:

【中文标题】TypeError:X 类型的对象不是 JSON 可序列化的【英文标题】:TypeError: Object of type X is not JSON serializable 【发布时间】:2019-03-27 03:48:20 【问题描述】:

我怎样才能返回一个包含对象数组的正确字典? 我正在制作一个烧瓶 API,但没有得到很好的结果,以后可以将其用作 json 对象。

这是输出以及我的制作方法 输出:


    "starttime": "2018-10-19 12:10:00",
    "endtime": "2018-10-19 12:11:00",
    "env": "TEST",
    "statistics": "\"TEST\": \"queryUsers\": \"calls\": 43, \"avgtime\": 1, \"errors\": 0, \"first_error\": null, \"last_error\": null, \"timeouts\": 0, \"first_to\": null, \"last_to\": null,
...

路由器:

def get(self, env):
if env == 'TEST':
    start = "2018-10-19 12:10:00"
    end = "2018-10-19 12:11:00"
    stats = self.scontroller.getStatistics(start, end, 'ALL')

    return 'starttime': start, 'endtime': end, 'env': env, 'statistics': json.dumps(stats, cls=MyJSONEncoder), 200

return "ENV not found", 404

如果我尝试返回这个

return 'starttime': start, 'endtime': end, 'env': env, 'statistics': stats, 200

我会得到:

    raise TypeError(f'Object of type o.__class__.__name__ '
    TypeError: Object of type Statistic is not JSON serializable

我的 json 编码器:

class MyJSONEncoder(JSONEncoder):
    def default(self, obj):
        if isinstance(obj, Metric):
            pass
        if isinstance(obj, Statistic):
            return vars(obj)

        return JSONEncoder.default(self, obj)

应该进入统计数据的dict遵循以下模型:


  "ENVNAME":
            "APINAME":
                           <Object Statistic>,
                           <Object Statistic>,
                           <Object Statistic>,
                           <Object Statistic>
                       ,
            "ANOTHERAPI": ...
           

它是这样安装的:

统计.py

class Statistic():

def __init__(self, calls, avgtime, errors, first_error, last_error, timeouts, first_to, last_to):
    self.calls = calls
    self.avgtime = avgtime
    self.errors = errors
    self.first_error = first_error
    self.last_error = last_error
    self.timeouts = timeouts
    self.first_to = first_to
    self.last_to = last_to

在控制器上:

stats[env][api] = Statistic(calls, avgtime, errors, first_er, last_er, tos, first_to, last_to)

感谢任何帮助。

谢谢!

【问题讨论】:

请不要这样做......未来你会感谢你......或你的同事 @JoranBeasley 你有什么推荐? 向你的类添加一个 to_dict() ,它将返回你的类的 dict 表示......并且可能添加一个 from dict 以允许你从该 dict 重建它......总是首选显式过度隐含... 这将是一个仅用于获取数据的 api,并且 jsonify 运行良好,如下面的响应所示。我还应该为每一节课都这样做吗? 问题在于编码器隐藏了功能并且是非标准的......当某些东西不起作用时,它可能很难追踪 【参考方案1】:

已通过在应用启动器中使用 flask.jsonify() 并声明 app.json_encoder = MyJSONEncoder 进行修复。

        response = jsonify(starttime=start, endtime=end, env=env, statistics=stats)
        response.status_code = 200
        return response

希望它也对其他人有所帮助。

【讨论】:

你好,我推荐使用flask jsonify()而不是json.dums(),但是更多细节,你可以阅读这个answer,它有很好的解释 嗨@RolandasŠimkus,这工作得很好。谢谢

以上是关于TypeError:X 类型的对象不是 JSON 可序列化的的主要内容,如果未能解决你的问题,请参考以下文章

TypeError:“标签”类型的对象不是 JSON 可序列化的

Python 错误:TypeError:'Timestamp' 类型的对象不是 JSON 可序列化的'

Celery EncodeError(TypeError('响应类型的对象不是 JSON 可序列化的'))

TypeError:mappingproxy 类型的对象不是 JSON 可序列化的

TypeError:“float32”类型的对象不是 JSON 可序列化的 [重复]

Json jwt 令牌问题 - TypeError:“用户”类型的对象不是 JSON 可序列化的