如何将 ujson 用作 Flask encoder/decoder?

How can I use ujson as a Flask encoder/decoder?

我看到曾经可以像这样在 Flask 应用程序中使用 simplejson 作为 JSON 编码器/解码器:

from simplejson import JSONEncoder, JSONDecoder

app.json_encoder = JSONEncoder
app.json_decoder = JSONDecoder

但是ujson没有这样的对象:

>>> from ujson import JSONEncoder
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: cannot import name 'JSONEncoder' from 'ujson' (/.../site-packages/ujson.cpython-38-x86_64-linux-gnu.so

我试过的

我想到了这样的事情:

from uuid import UUID, uuid4

import ujson as json
from flask import Flask, jsonify
from flask.json import JSONEncoder


class CustomJSONEncoder(JSONEncoder):
    def default(self, obj):
        if isinstance(obj, UUID):
            return str(obj)
        return JSONEncoder.default(self, obj)

    def encode(self, o):
        return json.dumps(o)


app = Flask(__name__)
app.json_encoder = CustomJSONEncoder


@app.route("/")
def index():
    return jsonify({"foo": uuid4()})


app.run()

但我不确定,因为对解码器的帮助显示如下:

 |  decode(self, s, _w=<built-in method match of re.Pattern object at 0x7f6a608404b0>, _PY3=True)
 |      Return the Python representation of ``s`` (a ``str`` or ``unicode``
 |      instance containing a JSON document)
 |  
 |  raw_decode(self, s, idx=0, _w=<built-in method match of re.Pattern object at 0x7f6a608404b0>, _PY3=True)
 |      Decode a JSON document from ``s`` (a ``str`` or ``unicode``
 |      beginning with a JSON document) and return a 2-tuple of the Python
 |      representation and the index in ``s`` where the document ended.
 |      Optionally, ``idx`` can be used to specify an offset in ``s`` where
 |      the JSON document begins.
 |      
 |      This can be used to decode a JSON document from a string that may
 |      have extraneous data at the end.

我的实现没问题吗?我将如何支持那些其他参数? decode什么时候用,什么时候用raw_decode

当我 运行 这个时,我得到:

[2020-10-09 10:54:52,063] ERROR in app: Exception on / [GET]
Traceback (most recent call last):
  File "/home/moose/.pyenv/versions/3.8.3/lib/python3.8/site-packages/flask/app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/moose/.pyenv/versions/3.8.3/lib/python3.8/site-packages/flask/app.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/moose/.pyenv/versions/3.8.3/lib/python3.8/site-packages/flask/app.py", line 1821, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/moose/.pyenv/versions/3.8.3/lib/python3.8/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/home/moose/.pyenv/versions/3.8.3/lib/python3.8/site-packages/flask/app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/moose/.pyenv/versions/3.8.3/lib/python3.8/site-packages/flask/app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "main.py", line 28, in index
    return jsonify({"foo": uuid4()})
  File "/home/moose/.pyenv/versions/3.8.3/lib/python3.8/site-packages/flask/json/__init__.py", line 370, in jsonify
    dumps(data, indent=indent, separators=separators) + "\n",
  File "/home/moose/.pyenv/versions/3.8.3/lib/python3.8/site-packages/flask/json/__init__.py", line 211, in dumps
    rv = _json.dumps(obj, **kwargs)
  File "/home/moose/.pyenv/versions/3.8.3/lib/python3.8/site-packages/simplejson/__init__.py", line 398, in dumps
    return cls(
  File "main.py", line 14, in encode
    return json.dumps(o)
TypeError: UUID('1f45a2bc-c964-48f0-b2f5-9ef7a2557966') is not JSON serializable

您可以像这样使用 try 块:

import ujson as json
from flask.json import JSONEncoder


class CustomJSONEncoder(JSONEncoder):
    def default(self, obj):
        try:
            return json.dumps(obj)
        except TypeError:
            return JSONEncoder.default(self, obj)


from flask import Flask

app = Flask(__name__)
app.json_encoder = CustomJSONEncoder