Поведение Python для богатого сравнения (Или, когда Десятичное число ('100.0') <.01)

Таким образом, у меня есть один лайнер:

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

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

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

>>> 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 в первом случае, и Верный во втором? bool (NotImplemented) должен быть константой.

  3. Это просто отступает к идентификатору () проверка? Это кажется не (или да, но назад):

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

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

5
задан mskfisher 4 June 2012 в 17:11
поделиться

2 ответа

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

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

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

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

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

6
ответ дан 14 December 2019 в 13:28
поделиться

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

(True, False, NotImplemented, NotImplemented)

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

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

0
ответ дан 14 December 2019 в 13:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: