Re 1, это действительно то поведение, которое мы разработали - правильное или неправильное, каким оно может быть (извините, если это испортило ваш вариант использования, но мы пытались быть общими!).
В частности, долгое время случалось так, что каждый объект Python мог подвергаться сравнению неравенства с любыми другими - объекты типов, которые на самом деле не сравнимы, сравниваются произвольно (последовательно в данном прогоне, не обязательно между прогонами); Основным вариантом использования была сортировка разнородного списка для группировки в нем элементов по типу.
Исключение было введено только для комплексных чисел, что делало их несопоставимыми с чем-либо - но это было еще много лет назад, когда мы время от времени проявляли осторожность в нарушении совершенно хорошего пользовательского кода. В настоящее время мы гораздо строже относимся к обратной совместимости в основном выпуске (например, вдоль линии 2.*
и отдельно по линии 3.*
, хотя несовместимости допускаются между 2 и 3 - действительно, это вся суть в серии a 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, я бы использовал фабричную функцию, такую как
def to_decimal(float_price):
return decimal.Decimal('%.2f' % float_price)
, поскольку после получения полученное десятичное число является совершенно обычным.