2010-11-03 10 views
2

[Python 3.1]подклассы поплавка, чтобы заставить точность неподвижной точки печати в питоне

Я следую на this answer:

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

Я знаю, что нужно следить за своими флоят литералы (т.е. заменить 3.0 на prettyfloat(3.0) и т. д.), и все в порядке.

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

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

EDIT:

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

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

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

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

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

Спасибо!

+0

Простейшим способом форматирования может быть использование 'decimal.Decimal'. Что в этом плохого? –

+0

Я еще не видел случай, когда подклассификация типа ядра типа 'float' - это правильная вещь. –

+0

@ S.Lott Мне нужно ровно две десятичные цифры; и мне нужно это во всем коде, в том числе, где я печатаю словарь со значениями float внутри. @Glenn Maynard У меня также нет большой надежды :(Просто подумал, может быть, есть чистый способ заставить его работать. – max

ответ

5

Я имел посмотрите на ответ, который вы проследили дальше, и я думаю, вы вводите в заблуждение данные и его .

@Robert Rossney предложил подкласс 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. 

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

3

, что из-за 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

В качестве примера такого рода поиска вы попадете именно с такими вещами, результаты из 'prettyfloat (1.12345) + 1.12345' и' 1.12345 + prettyfloat (1.12345) 'очень разные. –

+0

yeap, почему он не должен этого делать, он может сделать его более уродливым, выполняя некоторые проверки типа каждый раз, чтобы решить эту проблему:) – mouad

1

decimal. Для этого это и есть.

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

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

+1

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

+0

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

+0

@Glenn: Я считаю, что есть короткое окно после публикации, где вы можете редактировать, не отмечая свое сообщение как отредактированное. Вы действительно правы, конечно =). – katrielalex

Смежные вопросы