Python到JSON序列化在Decimal上失败

Din*_*esh 30 python json decimal

我有一个包含一些小数的python对象.这导致json.dumps()中断.

我从SO得到了以下解决方案(例如Python JSON序列化一个Decimal对象),但重新解决的解决方案仍然不起作用.Python网站 - 有完全相同的答案.

有任何建议如何使这项工作?

谢谢.以下是我的代码.看起来dumps()甚至没有进入专门的编码器.

clayton@mserver:~/python> cat test1.py
import json, decimal

class DecimalEncoder(json.JSONEncoder):
        def _iterencode(self, o, markers=None):
                print "here we go o is a == ", type(o)
                if isinstance(o, decimal.Decimal):
                        print "woohoo! got a decimal"
                        return (str(o) for o in [o])
                return super(DecimalEncoder, self)._iterencode(o, markers)

z = json.dumps( {'x': decimal.Decimal('5.5')}, cls=DecimalEncoder )
print z
clayton@mserver:~/python> python test1.py
Traceback (most recent call last):
  File "test1.py", line 11, in <module>
    z = json.dumps( {'x': decimal.Decimal('5.5')}, cls=DecimalEncoder )
  File "/home/clayton/python/Python-2.7.3/lib/python2.7/json/__init__.py", line 238, in dumps
    **kw).encode(obj)
  File "/home/clayton/python/Python-2.7.3/lib/python2.7/json/encoder.py", line 201, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/home/clayton/python/Python-2.7.3/lib/python2.7/json/encoder.py", line 264, in iterencode
    return _iterencode(o, 0)
  File "/home/clayton/python/Python-2.7.3/lib/python2.7/json/encoder.py", line 178, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: Decimal('5.5') is not JSON serializable
clayton@mserver:~/python>
Run Code Online (Sandbox Code Playgroud)

Mar*_*ers 70

它(不再)建议你创建一个子类; 的json.dump()json.dumps()函数采用一个default函数:

def decimal_default(obj):
    if isinstance(obj, decimal.Decimal):
        return float(obj)
    raise TypeError

json.dumps({'x': decimal.Decimal('5.5')}, default=decimal_default)
Run Code Online (Sandbox Code Playgroud)

演示:

>>> def decimal_default(obj):
...     if isinstance(obj, decimal.Decimal):
...         return float(obj)
...     raise TypeError
... 
>>> json.dumps({'x': decimal.Decimal('5.5')}, default=decimal_default)
'{"x": 5.5}'
Run Code Online (Sandbox Code Playgroud)

您找到的代码仅适用于Python 2.6并覆盖了在以后的版本中不再调用的私有方法.

  • 转换为“ float”会失去准确性;重复项包含不丢失任何方法。 (3认同)

Fea*_*ure 20

我无法相信这里没有人谈到使用simplejson,它支持开箱即用的Decimal反序列化.

import simplejson
from decimal import Decimal

simplejson.dumps({"salary": Decimal("5000000.00")})
'{"salary": 5000000.00}'

simplejson.dumps({"salary": Decimal("1.1")+Decimal("2.2")-Decimal("3.3")})
'{"salary": 0.0}'
Run Code Online (Sandbox Code Playgroud)

  • 使用simplejson有这样的缺点吗?否则,为什么这么多的答案难以解决? (3认同)
  • 似乎 simplejson 已经过了几天,至少作为 Django https://docs.djangoproject.com/en/1.8/internals/deprecation/#deprecation-removed-in-1-7 的默认部分 (2认同)

Fra*_*ant 16

如果您正在使用Django.Decimal和date字段有一个很棒的类:

https://docs.djangoproject.com/en/1.10/topics/serialization/#djangojsonencoder

要使用它:

import json
from django.core.serializers.json import DjangoJSONEncoder

json.dumps(value, cls=DjangoJSONEncoder)
Run Code Online (Sandbox Code Playgroud)