我想在mthon中将mongoDb的输出序列化为实际的VALID json。我找到了几个库,但似乎没有一个生成有效的json 和处理不兼容的值为null (未定义也可以。)
示例输入:
{
"_id" : ObjectId("57f3e32c71285f85b46d6fb5"),
"rate" : Infinity
"value" : NaN
}
预期输出:
(尝试了json.dumps及其allow_nan选项,但它会抛出错误而且根本没有帮助)
{
"_id" : { $oid: "57f3e32c71285f85b46d6fb5" },
"rate" : null,
"value" : null
}
任何人都知道方法/图书馆来实现这个目标吗?
作为一个例子,Javascript的JSON做得很好:
Object {_id: "57f3e32c71285f85b46d6fb5", rate: Infinity, value: NaN}
JSON.stringify(tg)
"{"_id":"57f3e32c71285f85b46d6fb5","rate":null,"value":null}"
答案 0 :(得分:2)
你总是可以制作自己的编码器(我从https://gist.github.com/pauloalem/6244976偷走了这个编码器)
import json
class FloatEncoder(json.JSONEncoder):
def __init__(self, nan_str="null", **kwargs):
super(FloatEncoder, self).__init__(**kwargs)
self.nan_str = nan_str
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.encode_basestring,
_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)
d = {"i_will_byte_you_in_the_ass": float("NaN")}
print( json.dumps(d, cls=FloatEncoder) )