Python: Почему у класса int нет богатых операторов сравнения, таких как `__lt __ ()`?

В основном любопытно.

Я заметил (по крайней мере, в п. 2.6 и 2.7), что у float есть все знакомые богатые функции сравнения: __lt__() , __gt__ , __eq__ и т. Д.

 >>> (5.0).__gt__(4.5) True 

но int не

 >>> (5).__gt__(4) Traceback (most recent call last): File "<input>", line 1, in <module> AttributeError: 'int' object has no attribute '__gt__' 

Что странно для меня, потому что сам оператор отлично работает

 >>> 5 > 4 True 

Даже строки поддерживают функции сравнения

 >>> "hat".__gt__("ace") True 

но все int имеет значение __cmp__()

Кажется странным для меня, и поэтому мне было интересно, почему это произошло.

Просто протестирован и работает так, как ожидалось, в python 3, поэтому я принимаю некоторые унаследованные причины. Еще хотелось бы услышать правильное объяснение, хотя;)

3 Solutions collect form web for “Python: Почему у класса int нет богатых операторов сравнения, таких как `__lt __ ()`?”

Если мы посмотрим на PEP 207 для Rich Comparisions, то это интересное предложение в конце:

Вложенная уже существующая, которая имеет дело с целыми сравнениями, по-прежнему будет применяться, что приведет к отсутствию производительности для наиболее распространенных случаев.

Таким образом, кажется, что в 2.x существует оптимизация для целочисленного сравнения. Если мы посмотрим на исходный код, мы можем найти это:

 case COMPARE_OP: w = POP(); v = TOP(); if (PyInt_CheckExact(w) && PyInt_CheckExact(v)) { /* INLINE: cmp(int, int) */ register long a, b; register int res; a = PyInt_AS_LONG(v); b = PyInt_AS_LONG(w); switch (oparg) { case PyCmp_LT: res = a < b; break; case PyCmp_LE: res = a <= b; break; case PyCmp_EQ: res = a == b; break; case PyCmp_NE: res = a != b; break; case PyCmp_GT: res = a > b; break; case PyCmp_GE: res = a >= b; break; case PyCmp_IS: res = v == w; break; case PyCmp_IS_NOT: res = v != w; break; default: goto slow_compare; } x = res ? Py_True : Py_False; Py_INCREF(x); } else { slow_compare: x = cmp_outcome(oparg, v, w); } 

Таким образом, кажется, что в 2.x существовала существующая оптимизация производительности – позволяя C-коду сравнивать целые числа напрямую – которые не были бы сохранены, если бы были реализованы богатые операторы сравнения.

Теперь в Python 3 __cmp__ больше не поддерживается, поэтому должны присутствовать операторы сравнения. Это не влияет на производительность, насколько я могу судить. Например, сравните:

 Python 2.7.1 (r271:86832, Jun 16 2011, 16:59:05) [GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import timeit >>> timeit.timeit("2 < 1") 0.06980299949645996 

чтобы:

 Python 3.2.3 (v3.2.3:3d0686d90f55, Apr 10 2012, 11:25:50) [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import timeit >>> timeit.timeit("2 < 1") 0.06682920455932617 

Таким образом, похоже, что подобная оптимизация существует, но моя догадка заключается в том, что решение суда заключалось в том, что их размещение в ветке 2.x было бы слишком большим изменением, если бы обратная совместимость была предметом рассмотрения.

В 2.x, если вы хотите что-то вроде богатых методов сравнения, вы можете получить их через модуль operator :

 >>> import operator >>> operator.gt(2,1) True 

__cmp__() – старомодный способ выполнения сравнений и устарел в пользу богатых операторов ( __lt__ , __le__ и т. д.), которые были введены только в Python 2.1. Вероятно, переход не был полным с 2.7.x – тогда как в Python 3.x __cmp__ полностью удален.

Haskell имеет самую изящную реализацию, которую я видел, – это тип данных Ord (порядковый номер), вам просто нужно определить, как работают < и = , а сам typeclass поставляет реализации по умолчанию для <= , > и >= в терминах из тех двух (которые вы более чем можете определить, если хотите). Вы можете написать такой класс самостоятельно в Python, не знаете, почему это не по умолчанию; возможно, по производительности.

Как сказал hircus, сравнения стиля __cmp__ устарели в пользу богатых операторов ( __lt__ , …) в Python 3. Первоначально сравнения были реализованы с использованием __cmp__ , но существуют некоторые типы / ситуации, когда простого оператора __cmp__ недостаточно ( например, экземпляры класса Color могут поддерживать == и != , но не < или > ), поэтому были добавлены операторы с богатым сопоставлением, оставив __cmp__ вместо обратной совместимости. Следуя философии питона: «Должен быть один – и желательно только один – простой способ сделать это» 1, прежняя поддержка была удалена в Python 3, когда можно было пожертвовать обратно совместимостью.

В Python 2, в то время как int все еще использует __cmp__ чтобы не нарушать совместимость с __cmp__ , не все числа с плавающей запятой меньше, больше или равны другим числам с плавающей запятой (например, (float('nan') < 0.0, float('nan') == 0.0, float('nan') > 0.0) оценивается как (False, False, False) , так что должно float('nan').__cmp__(0.0) return?), поэтому float необходимо использовать более новые богатые операторы сравнения.

1 : Попробуйте ввести «импортировать это» в оболочку python.

  • ctypes возвращает строку из c функции
  • Есть ли эквивалент Python для интерполяции строк Ruby?
  • Как я могу передать своих местных жителей и получить доступ к переменным непосредственно из другой функции?
  • питон? (условный / тернарный) оператор для присвоений
  •  
    Interesting Posts for Van-Lav

    Kivy 1.9.0 Пакет Windows KeyError: 'rthooks'

    Numpy уникальная 2D-подматрица

    Запоминание SQL-запросов

    Почему я не могу забрать трассировку ошибки в Python?

    Каково имя этого оператора «_» в Python?

    Недопустимый и / или отсутствующий сертификат SSL

    Как удалить контур маркера круга при использовании pyplot.plot в matplotlib

    Модуль python win32com.adsi ограничивает количество возвращаемых элементов из AD

    Как справиться с производительностью создания подписанных URL-адресов для доступа к частному контенту через CloudFront?

    Как мне заставить Python 2.x и 3.x сосуществовать?

    Как динамически выбрать каталог шаблонов, который будет использоваться в колбе?

    Сканирование на незащищенном веб-сайте

    Как легко загружать файлы на сервер с помощью Javascript (для чайников)

    Инструмент (или комбинация инструментов) для воспроизводимых сред в Python

    Как я могу запустить команду управления django по заданию cron

    Python - лучший язык программирования в мире.