Поведение Python для расширенного сравнения (или, когда Decimal ('100.0') <.01) - PullRequest
5 голосов
/ 14 мая 2010

Итак, у меня есть один вкладыш:

import decimal; h = decimal.Decimal('100.0'); (h > .01, h < .01, h.__gt__(.01), h.__lt__(.01))

Все, что он делает - это создает десятичный объект, содержащий 100.0, и сравнивает его с 0,01 (float) различными способами.

Мой результат:

>>> import decimal; h = decimal.Decimal('100.0'); (h > .01, h < .01, h.__gt__(.01), h.__lt__(.01))
(False, True, NotImplemented, NotImplemented)

Из документов: «Метод расширенного сравнения может вернуть одноэлементный NotImplemented, если он не реализует операцию для данной пары аргументов.»

Так что на самом деле здесь три вопроса.

  1. Когда метод расширенного сравнения возвращает NotImplemented, что происходит? Почему не возникает исключение?

  2. Когда он получает NotImplemented, почему он возвращает False в первом случае и True во втором? bool (NotImplemented) должен быть константой.

  3. Просто возвращается к проверке id ()? Кажется нет (или да, но в обратном направлении):

(игнорируйте эту строку, форматирование испорчено, и это исправляет это)

from decimal import Decimal
h = Decimal('100.0')
f = .01
print h < f, id(h) < id(f)
print h > f, id(h) > id(f)

Мои результаты были проверены на:

Python 2.6.4 (r264:75708, Oct 26 2009, 08:23:19) [MSC v.1500 32 bit (Intel)] on win32
Python 2.6.5 (r265:79096, Mar 19 2010, 21:48:26) [MSC v.1500 32 bit (Intel)] on win32

Редактировать: Документация по оформлению заказа: http://docs.python.org/library/stdtypes.html#comparisons

Ответы [ 2 ]

6 голосов
/ 14 мая 2010

Когда возвращается метод расширенного сравнения Не реализовано, что происходит? Зачем разве это не вызывает исключение?

делегирует обратному методу (например, __lt__, когда оператор равен >) RHS при сравнении (float) - который в этом случае также возвращает NotImplemented - и, наконец, возвращается к Python 2 глупых старых правила для разнородных сравнений.

Когда он не реализован, почему в первом случае возвращается False, и Правда во втором? bool (NotImplemented) должен быть постоянная.

Нет bool задействовано - поскольку обе стороны сравнения возвращают NotImplemented (из-за преднамеренного решения по проекту НЕ поддерживать какие-либо операции между десятичными числами и числами с плавающей запятой), старые глупые правила используются как запасной вариант (и в недавнем - достаточно версии будут сравнивать типы, а не экземпляры - следовательно, id не имеет к этому никакого отношения). В Python 3 такое неподдерживаемое гетерогенное сравнение приведет к сбою и вызовет явное исключение, но в Python 2 для обратной совместимости этого просто не может быть - он должен вести себя глупо, как в течение всей жизни Python 2.

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

0 голосов
/ 14 мая 2010

У меня есть Python 2.6.4, и ваш пример работает нормально, то есть я нахожу

(True, False, NotImplemented, NotImplemented)

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

О id: id не имеет ничего общего со сравнениями , поэтому ни при каких обстоятельствах нельзя сравнивать a и b с id(a) < id(b), что не имеет никакого смысла. id немного напоминает адрес в памяти, поэтому сравнивать их не имеет никакого смысла.

...