如何将Python Decimal编码为Json Number [重复]

2skhul33  于 2023-08-02  发布在  Python
关注(0)|答案(2)|浏览(114)

此问题在此处已有答案

Python JSON serialize a Decimal object(24回答)
10小时前关闭。
如何将Decimal("123456789012345.99")转换为json编号123456789012345.99
Python 3.11 win64

import json
from decimal import Decimal

class DecimalToFloat(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, Decimal):
            return float(obj)
        return json.JSONEncoder.default(self, obj)

class DecimalToStr(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, Decimal):
            return str(obj)
        return json.JSONEncoder.default(self, obj)

obj = {'decimal':Decimal("123456789012345.99")}

# {"decimal": 123456789012345.98} - WRONG!!!!
print(json.dumps(obj, cls=DecimalToFloat)) 

# {"decimal": "123456789012345.99"} - json string
print(json.dumps(obj, cls=DecimalToStr)) 

# ??? {"decimal": 123456789012345.99}

字符串

UPD

simplejson模块正常

# {"decimal": 123456789012345.99}
print(simplejson.dumps(obj, use_decimal=True))


有没有一种方法可以在没有外部依赖的情况下对标准库做同样的事情?

iugsix8n

iugsix8n1#

您面临的问题是由于Python中浮点表示的限制,它使用双精度浮点数。另一方面,Decimal类提供了任意精度的十进制算术,它可以精确地处理大数字和固定小数位。
将Decimal(“123456789012345.99”)转换为浮点数时,浮点数表示无法精确表示十进制数,从而导致精度略有损失。结果,浮点表示变为123456789012345.98。
要保持原始的十进制精度,您可以使用自定义JSON编码器将Decimal对象转换为字符串:

import json
from decimal import Decimal

class DecimalToStr(json.JSONEncoder):
def default(self, obj):
    if isinstance(obj, Decimal):
        return str(obj)
    return super().default(obj)

obj = {'decimal': Decimal("123456789012345.99")}

# Output: {"decimal": "123456789012345.99"}
print(json.dumps(obj, cls=DecimalToStr))

字符串
通过使用DecimalToStr JSON编码器,Decimal对象将被转换为它的字符串表示,并在JSON输出中保留原始的十进制精度。
请记住,当您使用DecimalToStr时,十进制值将在JSON输出中表示为字符串。如果需要在JSON中将数字用作浮点数(例如,为了与其他系统的互操作性),您将遇到浮点数表示的固有限制,如初始代码所示。在这种情况下,通常最好将小数保留为字符串,以避免精度问题。

vhmi4jdf

vhmi4jdf2#

import json
from decimal import Decimal

d = Decimal("123456789012345.99")

s = str(d)

json_obj = {"number": s}

json_str = json.dumps(json_obj)

print(json_str) # outputs: {"number": "123456789012345.99"}

字符串

相关问题