создание подкласса float для обеспечения точности печати с фиксированной запятой в python - PullRequest
2 голосов
/ 04 ноября 2010

[Python 3.1]

Я отслеживаю этот ответ :

class prettyfloat(float):
  def __repr__(self):
    return "%0.2f" % self

Я знаю, что мне нужно отслеживатьиз моих литералов с плавающей точкой (то есть замените 3.0 на prettyfloat(3.0) и т. д.), и это нормально.

Но всякий раз, когда я делаю какие-либо вычисления, prettyfloat объекты преобразуются в float.

Какой самый простой способ исправить это?

РЕДАКТИРОВАТЬ:

Мне нужно ровно две десятичные цифры;и мне это нужно по всему коду, в том числе там, где я печатаю словарь со значениями float внутри.Это затрудняет использование любых функций форматирования.

Я не могу использовать Decimal глобальные настройки, так как я хочу, чтобы вычисления были с полной точностью (просто печатать с двумя десятичными точками).

@ Гленн Мейнард: я согласен, я не должен отменять __repr__;во всяком случае, это было бы просто __str__.Но это спорный вопрос из-за следующего:

@ Гленна Мейнарда и @singularity: я не буду подклассов float, так как я согласен, что в конце это будет выглядеть очень уродливо.

Я перестану пытаться быть умным, и просто буду вызывать функцию везде, где печатается float.Хотя мне очень грустно, что я не могу переопределить __str__ во встроенном классе float.

Спасибо!

Ответы [ 3 ]

5 голосов
/ 04 ноября 2010

Я посмотрел на ответ, за которым вы последовали, и я думаю, что вы путаете данные и их представление .

@ Роберт Росни предложил создать подкласс float, чтобы вы могли map () итерацию стандартного, не фальсифицированного floats в prettyfloats для отображения :

# Perform all our computations using standard floats.
results = compute_huge_numbers(42)
# Switch to prettyfloats for printing.
print(map(prettyfloat, results))

Другими словами, вы не должны (и не должны) использовать prettyfloat в качестве замены float везде в вашем коде.

Конечно, наследование от float для решения этой проблемы является излишним, так как это проблема представления, а не проблема данных. Достаточно простой функции:

def prettyfloat(number):
    return "%0.2f" % number  # Works the same.

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

3 голосов
/ 04 ноября 2010

это потому что prettyfloat (op) prettyfloat не возвращает prettyfloat

пример:

>>> prettyfloat(0.6)
0.60  # type prettyfloat
>>> prettyfloat(0.6) + prettyfloat(4.4)
5.0  # type float
Решение

, если вы не хотите приводить результат каждой операции вручную к prettyfloat и , если вы все еще хотите использовать prettyfloat, заключается в отмене всех операторов.

пример с оператором __add__ (что некрасиво)

class prettyfloat(float):
  def __repr__(self):
      return "%0.2f" % self
  def __add__(self, other):
      return prettyfloat(float(self) + other)

>>> prettyfloat(0.6) + prettyfloat(4.4)
5.00

делая это, я думаю, вам также придется изменить имя с prettyfloat на uglyfloat :), надеюсь, это поможет

1 голос
/ 04 ноября 2010

Используйте decimal. Вот для чего.

>>> import decimal
>>> decimal.getcontext().prec = 2
>>> one = decimal.Decimal("1.0")
>>> three = decimal.Decimal("3.0")
>>> one / three
Decimal('0.33')

... если вы на самом деле не хотите работать с плавающими с полной точностью везде в вашем коде, но печатать их округленными до двух десятичных знаков. В этом случае вам нужно переписать логику печати. ​​

...