如何解决Python json 编码器将 Decimal 转换为 null
我正在使用 Flask 和 simplejson 并配置了一个自定义的 json 编码器来将 dicts 转换为 json。
Custon 编码器:
gen = []
class CustomJSONEncoder(json.JSONEncoder):
def default(self,o):
if isinstance(o,datetime):
return o.strftime('%Y-%m-%d %H:%M:%s')
if isinstance(o,date):
return o.strftime('%Y-%m-%d')
if isinstance(o,np.int64):
return int(o)
if isinstance(o,decimal.Decimal):
a = (str(o) for o in [o])
gen.append(a)
return a
def _iterencode(self,o,markers=None):
if isinstance(o,decimal.Decimal):
return (str(o) for o in [o])
return super(CustomJSONEncoder,self)._iterencode(o,markers)
def json_encode(data):
return CustomJSONEncoder().encode(data)
假设我有一个变量 b = [{"os": Decimal('7'),"num": 77777}]
。
如果我运行 json_encode(b)
。这导致 '[{"os": null,"num": 77777}]'
。 Decimal 值已转换为 null。
现在我通过仅返回 float(o)
来更改自定义编码器处理小数的方式来解决此问题。虽然这有效,但我想了解编码器的原始版本有什么问题。
我尝试在全局变量 gen
中捕获生成器对象并对其进行迭代。我可以看到值 7 正确出现。
完整的 ipython 控制台日志:
In [93]: bb
Out[93]: [{'os': Decimal('7'),'num': 77777}]
In [94]: gen = []
...: class CustomJSONEncoder(json.JSONEncoder):
...:
...: def default(self,o):
...: if isinstance(o,datetime):
...: return o.strftime('%Y-%m-%d %H:%M:%s')
...: if isinstance(o,date):
...: return o.strftime('%Y-%m-%d')
...: if isinstance(o,np.int64):
...: return int(o)
...: if isinstance(o,decimal.Decimal):
...: a = (str(o) for o in [o])
...: gen.append(a)
...: return a
...:
...:
...: def _iterencode(self,markers=None):
...: if isinstance(o,decimal.Decimal):
...: return (str(o) for o in [o])
...: return super(CustomJSONEncoder,markers)
...:
...:
...: def json_encode(data):
...: return CustomJSONEncoder().encode(data)
...:
In [95]: json_encode(bb)
Out[95]: '[{"os": null,"num": 77777}]'
In [96]: gen[0]
Out[96]: <generator object CustomJSONEncoder.default.<locals>.<genexpr> at 0x7f45cdb37990>
In [97]: next(gen[0])
Out[97]: '7'
问题究竟出在哪里?为什么 Decimal 返回 null ?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。