You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python标准库将Decimal编码为精确的JSON数字?

仅用Python标准库实现Decimal到JSON精确数字的序列化

在Python标准库json模块中,直接将Decimal转为float会丢失精度,转为字符串则会带上引号,无法得到精确的JSON数字格式。以下是仅依赖标准库的可靠实现方案:

安全实现方案(推荐)

通过给Decimal值添加唯一标记,避免误替换普通字符串,最终还原为精确的JSON数字:

import json
import re
from decimal import Decimal

class PreciseDecimalEncoder(json.JSONEncoder):
    def encode(self, obj):
        # 遍历对象,给Decimal值添加唯一标记
        def traverse(o):
            if isinstance(o, Decimal):
                return f"__DECIMAL_MARKER__{str(o)}"
            elif isinstance(o, dict):
                return {k: traverse(v) for k, v in o.items()}
            elif isinstance(o, (list, tuple)):
                return [traverse(i) for i in o]
            else:
                return o
        
        # 生成带标记的JSON字符串,再替换标记还原为数字
        processed_obj = traverse(obj)
        json_str = super().encode(processed_obj)
        json_str = re.sub(r'"__DECIMAL_MARKER__(.*?)"', r'\1', json_str)
        return json_str

# 测试示例
obj = {
    'decimal': Decimal("123456789012345.99"),
    'regular_string': "12345.99",
    'nested': {'value': Decimal("98765.43")}
}
result = json.dumps(obj, cls=PreciseDecimalEncoder)
print(result)
# 输出: {"decimal": 123456789012345.99, "regular_string": "12345.99", "nested": {"value": 98765.43}}

方案说明

  • 特殊标记__DECIMAL_MARKER__确保仅替换原本是Decimal的值,不会误改内容为数字的普通字符串。
  • 支持嵌套的字典、列表/元组结构中的Decimal值处理。

简洁实现方案(有局限)

如果能确保业务中没有内容与Decimal字符串表示完全一致的普通字符串,可直接替换数字格式的引号,但存在误替换风险:

import json
import re
from decimal import Decimal

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

obj = {'decimal': Decimal("123456789012345.99")}
json_str = json.dumps(obj, cls=SimpleDecimalEncoder)
json_str = re.sub(r'"(\d+\.?\d*)"', r'\1', json_str)
print(json_str)
# 输出: {"decimal": 123456789012345.99}

内容的提问来源于stack exchange,提问作者dimmaq

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 13:10:54