Почему десятичное число ('0')> 9999.0 истинно в Python? - PullRequest
5 голосов
/ 12 марта 2010

Это как-то связано с моим вопросом Почему ''> 0 True в Python?

В Python 2.6.4:

>> Decimal('0') > 9999.0
True

От ответа до моего исходного вопроса я понимаю, что при сравнении объектов различных типов в Python 2.x типы упорядочены по их имени. Но в этом случае:

>> type(Decimal('0')).__name__ > type(9999.0).__name__
False

Почему Decimal('0') > 9999.0 == True тогда?

ОБНОВЛЕНИЕ: Я обычно работаю в Ubuntu (Linux 2.6.31-20-generic # 57-Ubuntu SMP Mon 8 февраля 09:05:19 UTC 2010 i686 GNU / Linux, Python 2.6.4 (r264: 75706, 7 декабря) 2009, 18:45:15) [GCC 4.4.1] на linux2). В Windows (WinXP Professional SP3, Python 2.6.4 (r264: 75706, 3 ноября 2009 г., 13:23:17) [MSC v.1500 32 бит (Intel)] на win32) мое первоначальное утверждение работает по-другому:

>> Decimal('0') > 9999.0
False

Теперь я еще больше озадачен. % - (

Ответы [ 2 ]

12 голосов
/ 12 марта 2010

Поскольку десятичный модуль не сравнивается ни с одним типом, кроме long, int и Decimal. Во всех других случаях decimal молча возвращает «не то, что знает об объекте» как большее. Вы можете увидеть это поведение в функции _convert_other () decimal.py

Глупый, глупый десятичный класс.

О, см. Также http://bugs.python.org/issue2531.

Итак, вот что происходит:

  • Интерпретатор вызывает функцию сравнения Decimal.__gt__.
  • Decimal.__gt__ вызывает Decimal._convert_other для преобразования входящего числа в десятичное число.
  • Decimal._convert_other не понимает поплавки. Реализация вниз в Decimal._convert_other явно проверяет типы операндов long, int и Decimal. Да это ошибка, в которой неожиданные реализации библиотеки приводят к ошибкам в дальнейшем. Это было бы чище делать правильные вещи или даже просто через TypeException. Вместо он проходит через то же NotImplemented, что и сравнение десятичного числа с, скажем, хэш записей о сотрудниках.
  • Несколько других операций сравнения. Сравнение сдается.
  • Сравнение по умолчанию, вызывается в CPython's Objects / object.c / default_3way_compare
  • В Python 3 это справедливо barfs. В Python 2 сравниваются функции id ().
  • В Windows используется сравнение без учета регистра (вроде). На современных системах используется сравнение с учетом регистра.
  • Таким образом, вы получите разные результаты.

Мы уже там?

1 голос
/ 12 марта 2010
def __gt__(self, other, context=None):
    other = _convert_other(other)
    if other is NotImplemented:
        return other
    ans = self._compare_check_nans(other, context)
    if ans:
        return False
    return self._cmp(other) > 0


def _convert_other(other, raiseit=False):
    """Convert other to Decimal.

    Verifies that it's ok to use in an implicit construction.
    """
    if isinstance(other, Decimal):
        return other
    if isinstance(other, (int, long)):
        return Decimal(other)
    if raiseit:
        raise TypeError("Unable to convert %s to Decimal" % other)
    return NotImplemented
...