小能豆

Python JSON 序列化 Decimal 对象

javascript

我有Decimal('3.9')一个对象的一部分,并希望将其编码为 JSON 字符串,该字符串应类似于{'x': 3.9}。我不关心客户端的精度,因此浮点数就可以了。

有没有好的方法来序列化它? JSONDecoder 不接受 Decimal 对象,并且事先转换为浮点数会导致{'x': 3.8999999999999999}错误,并且会浪费大量带宽。


阅读 149

收藏
2024-07-17

共1个答案

小能豆

Decimal在 Python 中将对象序列化为 JSON,同时保留其预期的精度(在本例中,将其转换为浮点数而不保留不必要的精度),您可以使用模块中的default参数自定义序列化过程。以下是实现方法:json.dumps()``json

  1. 转换Decimalfloat精度受控的:由于 Pythonfloat采用二进制格式表示,因此有时会引入精度问题。但是,您可以通过将其转换为具有指定小数位数的字符串,然后将其解析回 来控制精度float
  2. 自定义 JSON 序列化:使用 的default参数json.dumps()指定一个函数,该函数将Decimal对象转换为具有受控精度的字符串,然后将这些字符串解析为float

以下代码示例演示了如何实现这一点:

import json
from decimal import Decimal

# Example object containing Decimal
data = {'x': Decimal('3.9')}

# Custom function to serialize Decimal to float with controlled precision
def decimal_default(obj):
    if isinstance(obj, Decimal):
        return float(f'{obj:.6f}')  # Adjust precision as needed
    raise TypeError(f'Object of type {type(obj)} is not JSON serializable')

# Serialize to JSON using custom function
json_str = json.dumps(data, default=decimal_default)

print(json_str)  # Output: {"x": 3.9}

解释:

  • decimal_default 函数:此函数检查对象是否是 的实例Decimal。如果是,则使用 Python 的格式化字符串文字(例如)将其转换为具有指定小数位数的字符串f'{obj:.6f}',然后将该字符串转换为float
  • json.dumps:该json.dumps()函数将 Python 对象转换为 JSON 字符串。通过指定default=decimal_default,它使用您的自定义函数来处理Decimal对象的序列化。
  • 控制精度f'{obj:.6f}':根据您的要求调整格式化字符串内的精度。这可确保在序列化为 JSON 之前将其Decimal转换为具有所需精度的表示形式。float

通过遵循此方法,您可以Decimal在 Python 中将对象序列化为 JSON,同时控制精度并避免由于浮点精度过高而导致不必要的带宽使用。'.6f'根据您的特定需求调整精度(在示例中)。

2024-07-17