【问题标题】:Flask TypeError 'is not JSON serializable' - nested dictionaryFlask TypeError '不是 JSON 可序列化的' - 嵌套字典
【发布时间】:2018-02-10 20:59:14
【问题描述】:

我正在使用 Flask 作为我的服务器的框架,在返回响应时出现以下错误:

> Traceback (most recent call last):
  File "C:\Python27\lib\site-packages\flask\app.py", line 1612, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:\Python27\lib\site-packages\flask\app.py", line 1598, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "C:\Python27\lib\site-packages\flask_restful\__init__.py", line 480, in wrapper
    resp = resource(*args, **kwargs)
  File "C:\Python27\lib\site-packages\flask\views.py", line 84, in view
    return self.dispatch_request(*args, **kwargs)
  File "C:\Python27\lib\site-packages\flask_restful\__init__.py", line 595, in dispatch_request
    resp = meth(*args, **kwargs)
  File "rest.py", line 27, in get
    return jsonify(**solution)
  File "C:\Python27\lib\site-packages\flask\json.py", line 263, in jsonify
    (dumps(data, indent=indent, separators=separators), '\n'),
  File "C:\Python27\lib\site-packages\flask\json.py", line 123, in dumps
    rv = _json.dumps(obj, **kwargs)
  File "C:\Python27\lib\json\__init__.py", line 251, in dumps
    sort_keys=sort_keys, **kw).encode(obj)
  File "C:\Python27\lib\json\encoder.py", line 209, in encode
    chunks = list(chunks)
  File "C:\Python27\lib\json\encoder.py", line 434, in _iterencode
    for chunk in _iterencode_dict(o, _current_indent_level):
  File "C:\Python27\lib\json\encoder.py", line 408, in _iterencode_dict
    for chunk in chunks:
  File "C:\Python27\lib\json\encoder.py", line 332, in _iterencode_list
    for chunk in chunks:
  File "C:\Python27\lib\json\encoder.py", line 332, in _iterencode_list
    for chunk in chunks:
  File "C:\Python27\lib\json\encoder.py", line 442, in _iterencode
    o = _default(o)
  File "C:\Python27\lib\site-packages\flask\json.py", line 80, in default
    return _json.JSONEncoder.default(self, o)
  File "C:\Python27\lib\json\encoder.py", line 184, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: {'origin': u'porto', 'dest': u'lisboa', 'price': '31', 'date': '2017-12-23', 'url': u'https://www.google.pt/flights/#search;f=opo;t=lis;d=2017-12-23;r=2017-12-24'} is not JSON serializable

我有以下功能:

from flask import Flask, request, jsonify
from flask_restful import Resource, Api
from flask_cors import CORS, cross_origin
from json import dumps
import flights
import solveProblem

app = Flask(__name__)
api = Api(app)
CORS(app)

class Flights(Resource):
    def get(self, data):
        print 'received data from client: ' + data
        solution = solveProblem.solve(data)
        print 'got the solution from the script! \nSOLUTION: \n'
        print solution
        return jsonify(solution)

api.add_resource(Flights, '/flights/<string:data>')

if __name__ == '__main__':
    app.run()

在调试问题时,我发现以下解决方案不起作用:

1) 返回解决方案而不是 {'solution': solution}

2)做jsonify(解决方案)

3) 做 jsonify(**solution)

以上都不适合我; 我想知道为什么会发生这种情况,当我试图返回一个有效的字典时:

{'flights': [[{'origin': u'porto', 'dest': u'lisboa', 'price': '31', 'date': '2017-12-23', 'url': u'https://www.google.pt/flights/#search;f=opo;t=lis;d=2017-12-23;r=2017-12-24'}]], 'cost': '31'}

感谢任何帮助。 谢谢

【问题讨论】:

  • solution 的类型是什么?你能print type(solution)print repr(solution) 分享输出吗?
  • soltuin['flights][0][0] ('dict'-) 里面的解决方案不是 dict 类型,而是 'Thesis. modules.Flight.Flight'> 我想这是错误,关于如何修复它的任何建议? @smarx
  • 是的,这听起来像是个问题。要么实现自定义 JSONEncoder,要么先将数据转换为 JSON 可序列化的内容。
  • 顺便说一句,该类型是返回以下内容的结果: def __repr__(self): #logger.info('INSIDE REPR') # return "origin: {}, destination: {} , 日期: {}, 价格: {} url: {}".format(# self._origin, self._dest, self._date, self._price, self._url) f_dict = { "origin": self._origin[ 0], "dest": self._dest[0], "date": self._date, "price": self._price, "url": self._url } return str(f_dict) 我想返回一个字典,但是python不允许,所以我用str
  • 当然,__repr__ 必须返回 str,但我不明白这与您遇到的问题有什么关系。

标签: json flask notserializableexception


【解决方案1】:

由于您的大多数函数都在其他地方声明,因此我编写了一个玩具 Flask 程序,只是为了传递您遇到的字典。 [编辑] 在我使用标准 python json 模块之前。我对其进行了编辑以使用烧瓶自己的 jsonify,并且 它仍然可以与直接字典一起使用。所以错误不是 OP 正在寻找的地方。

 {'flights': [[{'origin': u'porto', 'dest': u'lisboa', 'price': '31', 'date': '2017-12-23', 'url': u'https://www.google.pt/flights/#search;f=opo;t=lis;d=2017-12-23;r=2017-12-24'}]], 'cost': '31'}

以下程序运行并将字典作为 JSON 对象返回:

import flask

app = flask.Flask(__name__)

@app.route('/')
def hello():
    jdic = flask.jsonify( {'origin': u'porto', 'dest': u'lisboa', 'price': '31', 'date': '2017-12-23', 'url': u'https://www.google.pt/flights/#search;f=opo;t=lis;d=2017-12-23;r=2017-12-24'} )
    return jdic

if __name__ == '__main__':
    app.run()

【讨论】:

    【解决方案2】:

    我在使用 3 级嵌套字典时遇到了同样的问题;它是有效的,json 可序列化并且通过命令行 json.dumps 没有问题。但是,Flask 不想输出它:“TypeError”,不是 json 可序列化的。唯一的区别是我使用的是 Python 3.5。

    所以我将它复制为一个字符串(在命令行上是 json 可序列化的!)并传递给 Flask 输出,它起作用了。

    尝试将嵌套的json传递为

    eval(str(solution))

    并查看错误。这不是一个确定的解决方案,而是一种解决方法。

    希望对你有帮助。

    【讨论】:

    • 如果您处理用户提供的数据,这看起来特别危险。
    • 是的。在对其进行任何操作之前,应始终对用户输入进行清理。但这不是问题的重点
    【解决方案3】:

    flask-restful中,Resource类的get方法只需要返回python数据结构即可。所以只需删除jsonify。对于用户定义的对象,您可以使用marshal_with() 装饰器。 查看更多:https://flask-restful.readthedocs.io/en/latest/quickstart.html#a-minimal-api

    【讨论】:

    • 不起作用。仍然抱怨它不是 json 可序列化的。
    【解决方案4】:

    我发现,当响应不是纯 python 字典时,通常会发生此错误。这发生在我身上,因为我试图传递一个类对象。所以,为了解决这个问题,我创建了一个类方法,它返回一个描述对象的字典,并使用它来创建 json 响应。

    结论:使用纯python对象,很容易翻译成JSON。

    【讨论】:

      【解决方案5】:

      我的猜测是,当您创建“解决方案”时,分配给它的数据是格式不正确的字典

          {'item', 'value'}
      

      代替:

          {'item': 'value'}
      

      因此创建一个集合而不是一个字典

      【讨论】:

        【解决方案6】:

        当您尝试将数据列表转换为 json 时,我们不能直接使用 jsonify。 有两种方法可以将列表转换为字典,因为我们需要编写将列表数据转换为字典的函数,这是一项复杂的任务。 您可以使用 Marshmallow 库进行一项聪明的工作。它序列化了你列出的数据,之后你可以使用 jsonify。

        【讨论】:

          猜你喜欢
          • 2022-01-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-07-12
          • 1970-01-01
          • 2019-06-02
          • 1970-01-01
          相关资源
          最近更新 更多