我在json中编码无穷大时遇到问题。
json.dumps会将其转换为"Infinity",但我希望将其转换为null或我选择的其他值。

不幸的是,仅在转储尚不了解该对象的情况下,设置default参数才似乎有效,否则默认处理程序将被忽略。

有没有一种方法可以对对象进行预编码,更改对类型/类进行编码的默认方式,或者在正常编码之前将特定类型/类转换为其他对象?

最佳答案

在这里查看源代码:http://hg.python.org/cpython/file/7ec9255d4189/Lib/json/encoder.py
如果您将JSONEncoder子类化,则可以仅覆盖iterencode(self, o, _one_shot=False)方法,该方法为Infinity(在内部函数内部)具有显式的特殊大小写。
为了使其可重用,您还需要更改__init__以采用一些新选项,并将其存储在类中。
或者,您可以从pypi中选择一个json库,该库具有您要查找的适当可扩展性:https://pypi.python.org/pypi?%3Aaction=search&term=json&submit=search
这是一个例子:

import json

class FloatEncoder(json.JSONEncoder):

    def __init__(self, nan_str = "null", **kwargs):
        super(FloatEncoder,self).__init__(**kwargs)
    self.nan_str = nan_str

    # uses code from official python json.encoder module.
    # Same licence applies.
    def iterencode(self, o, _one_shot=False):
        """Encode the given object and yield each string
        representation as available.

        For example::

            for chunk in JSONEncoder().iterencode(bigobject):
                mysocket.write(chunk)
        """
        if self.check_circular:
            markers = {}
        else:
            markers = None
        if self.ensure_ascii:
            _encoder = json.encoder.encode_basestring_ascii
        else:
            _encoder = json.encoder.encode_basestring
        if self.encoding != 'utf-8':
            def _encoder(o, _orig_encoder=_encoder,
                         _encoding=self.encoding):
                if isinstance(o, str):
                    o = o.decode(_encoding)
                return _orig_encoder(o)

        def floatstr(o, allow_nan=self.allow_nan,
                     _repr=json.encoder.FLOAT_REPR,
                     _inf=json.encoder.INFINITY,
                     _neginf=-json.encoder.INFINITY,
                     nan_str = self.nan_str):
            # Check for specials. Note that this type of test is
            # processor and/or platform-specific, so do tests which
            # don't depend on the internals.

            if o != o:
                text = nan_str
            elif o == _inf:
                text = 'Infinity'
            elif o == _neginf:
                text = '-Infinity'
            else:
                return _repr(o)

            if not allow_nan:
                raise ValueError(
                    "Out of range float values are not JSON compliant: " +
                    repr(o))

            return text

        _iterencode = json.encoder._make_iterencode(
                markers, self.default, _encoder, self.indent, floatstr,
                self.key_separator, self.item_separator, self.sort_keys,
                self.skipkeys, _one_shot)
        return _iterencode(o, 0)


example_obj = {
    'name': 'example',
    'body': [
        1.1,
        {"3.3": 5, "1.1": float('Nan')},
        [float('inf'), 2.2]
    ]}

print json.dumps(example_obj, cls=FloatEncoder)
ideone:http://ideone.com/dFWaNj

关于python - 有没有办法重写python的json处理程序?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17503981/

10-12 18:03
查看更多