Ответ 1
Re 1, это действительно то поведение, которое мы разработали - правильно или неправильно, как может быть (извините, если это отключает ваш прецедент, но мы пытались быть генералом!).
В частности, долгое время каждый объект Python мог быть подвергнут неравенству по сравнению со всеми остальными - объекты типов, которые на самом деле не сравнимы, сравниваются произвольно (последовательно в данном пробеге, а не во всех прогонах); основной вариант использования - сортировка гетерогенного списка для группировки элементов в нем по типу.
Исключение было введено только для сложных чисел, что делало их несопоставимыми ни с чем, но это было еще много лет назад, когда мы были иногда кавалером, нарушая превосходный код пользователя. В настоящее время мы гораздо более жестко поддерживаем обратную совместимость в основном выпуске (например, вдоль строки 2.*
и отдельно по 3.*
), хотя несовместимости разрешены между 2 и 3 - действительно, что вся точка наличия 3.*
, позволяя нам исправить прошлые дизайнерские решения даже несовместимыми способами).
Произвольные сравнения оказались более трудными, чем они стоят, вызывая путаницу пользователя; и группировка по типу теперь может быть легко получена, например, с аргументом key=lambda x: str(type(x))
до sort
; поэтому в сравнении Python 3 между объектами разных типов, если только сами объекты специально не позволяют это в методах сравнения, вызывает исключение:
>>> decimal.Decimal('2.0') > 1.2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: Decimal() > float()
Другими словами, в Python 3 это ведет себя точно так, как вы думаете; но в Python 2 он не (и никогда не будет в любом Python 2.*
).
Re 2, вы будете в порядке - хотя посмотрите gmpy, поскольку я надеюсь, что это интересный способ конвертировать парные до бесконечноточных фракций через деревья Фаре. Если цены, с которыми вы имеете дело, точны не более центов, используйте '%.2f' % x
, а не repr(x)
! -)
Вместо подкласса Decimal я бы использовал функцию factory, такую как
def to_decimal(float_price):
return decimal.Decimal('%.2f' % float_price)
так как после его создания результирующее десятичное число является совершенно обычным.