Извлечение численного значения от Десятичного числа Python

Когда я использую объект Десятичного числа Python просто с чем-то как:

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

это распечатает 3.432, точно так же, как я хочу, но если я пытаюсь поместить тот же самый декабрь значения в объект json, что я вхожу в json, Десятичный ("3.432"). Как я могу просто получить численное значение от десятичного числа?

6
задан whatWhat 16 February 2010 в 00:31
поделиться

3 ответа

Вы получили десятичное число ('3.432') в своем объекте JSON? Странно ... как?

>>> 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 может это обработать. Вы все равно не получите Decimal обратно позже, если вы снова не конвертируете вручную из float ...

Edit: Девин Жанпьер указывает на существующую поддержку в модуле json для декодирования строк с плавающей запятой как нечто иное, чем float, с аргументом parse_float для load () , load () и пользовательских JSONDecoders. Хотя это потребует от вас сначала преобразовать ваши Decimals в числа с плавающей запятой при кодировании (с потерей точности), это может решить вторую половину проблемы немного более чисто, чем мой более ручной подход выше (обратите внимание, что он будет применяться ко всем плавающим в ваших данных JSON. ). Вы также должны иметь возможность создать подкласс JSONEncoder для записи цифр для Decimal без предварительного преобразования в float, что позволит избежать потери точности.

4
ответ дан 10 December 2019 в 00:38
поделиться
>>> str(decimal.Decimal('3.1'))
'3.1'

Готовый к работе JSON интенсивно использует несколько примитивных типов, например строки.

Лучше всего преобразовать десятичные дроби в строки при создании документа JSON из некоторого объекта Python.

Преобразование строк обратно в десятичное при преобразовании документа JSON обратно в объект Python.

5
ответ дан 10 December 2019 в 00:38
поделиться

Интересно - я получаю ошибку TypeError исключение (это для стандартного модуля Python 2.6 json - что вы используете?).

Очевидная альтернатива имеет очевидные недостатки:

>>> json.dumps(float(x))
'3.4319999999999999'
>>> json.dumps(str(x))
'"3.432"'

... один может дать вам довольно грязное приближение, другой обременяет вас кавычками. Если какая-либо из этих проблем допустима в вашем приложении, продолжайте, но ни одна из них не соответствует вашим точным спецификациям, как это сформулировано.

Самый простой (но не самый чистый !!!) способ сделать то, что вы хотите, со стандартным json , - это обезвредить что-нибудь:

>>> json.encoder.FLOAT_REPR=str
>>> json.dumps(float(x))
'3.432'

Правильный / чистый способ - сделать (и использовать ;-) подкласс json.Encoder , который использует str вместо repr для чисел с плавающей запятой - но это, увы, нетривиальный объем работы.

1
ответ дан 10 December 2019 в 00:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: