问题描述
我正在使用 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 (将#修改为@)