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 (将#修改为@)