从Python Decimal中提取数值

10 投票
5 回答
17426 浏览
提问于 2025-04-15 19:19

当我用Python的Decimal对象做一些简单的操作,比如:

from decimal import *
dec = Decimal('3.432')
print dec

它会输出3.432,正是我想要的。但是如果我试着把这个值放进一个json对象里,得到的结果却是Decimal("3.432")。我该怎么做才能只得到数字值,而不是这个Decimal对象呢?

5 个回答

2

你可以先把小数对象转换成字符串,然后再把这个字符串转换回小数:

>>> a = decimal.Decimal(3.0)
>>> str(a)
'3'
>>> int(str(a))
3
8
>>> str(decimal.Decimal('3.1'))
'3.1'

默认的JSON格式使用了一些基本的数据类型,比如字符串,这些类型用得很频繁。

最好的办法是在从某个Python对象创建JSON文档时,把你的Decimal(十进制数)转换成字符串。

然后在把JSON文档转换回Python对象时,再把字符串转换回Decimal。

8

你在你的 JSON 对象里看到了一个 Decimal('3.432')?这可真奇怪……怎么会这样呢?

>>> from decimal import *
>>> import json
>>> json.dumps(Decimal('3.432'))
....
TypeError: Decimal('3.432') is not JSON serializable

无论如何,如果你使用的是 Decimal 而不是 float,那么你可能不想通过转换成 float 来失去精度。如果是这样的话,你就得自己管理这个过程,首先确保你保留所有的数据,同时还要处理 JSON 不理解 Decimal 类型这个问题:

>>> j = json.dumps(str(Decimal('3.000')))
>>> j
'"3.000"'
>>> Decimal(json.loads(j))
Decimal('3.000')

当然,如果你对精度并不太在意(比如某个库的函数给你返回了一个 Decimal),那就先转换成 float,因为 JSON 是可以处理 float 的。不过要注意,除非你再次手动从 float 转换回来,否则你之后是无法得到 Decimal 的……

编辑:Devin Jeanpierre 提到,json 模块里有支持将 float 字符串解码为其他类型的功能,可以通过 parse_float 参数load()loads() 和自定义 JSONDecoder 中使用。虽然这需要你在编码时先把 Decimals 转换成 floats(这样会失去精度),但它可以比我上面提到的手动方法更干净地解决问题的后半部分(注意,这会影响到你 JSON 数据中的所有 floats)。你还可以创建一个 JSONEncoder 子类,直接输出 Decimal 的数字,而不需要先转换成 float,这样就可以避免精度的损失。

撰写回答