__ лейтенант __ вместо __ cmp __

1. Вы не должны всегда следовать веб-стандартам.

2. Вам не нужно комментировать свой код.

Пока это понятно незнакомцу.

95
задан Community 23 May 2017 в 11:55
поделиться

2 ответа

Да, легко реализовать все в терминах, например, __ lt __ с классом миксина (или метаклассом, или декоратором класса, если вам так нравится).

Например:

class ComparableMixin:
  def __eq__(self, other):
    return not self<other and not other<self
  def __ne__(self, other):
    return self<other or other<self
  def __gt__(self, other):
    return other<self
  def __ge__(self, other):
    return not self<other
  def __le__(self, other):
    return not other<self

Теперь ваш класс может определять только __ lt __ и умножать наследование от ComparableMixin (после любых других баз, которые ему нужны, если они есть). Декоратор класса был бы очень похож, просто вставляя аналогичные функции в качестве атрибутов нового класса, который он украшает (результат может быть микроскопически быстрее во время выполнения, при столь же незначительных затратах с точки зрения памяти).

Конечно, если ваш класс имеет какой-то особенно быстрый способ реализации (например) __ eq __ и __ ne __ , он должен определять их напрямую, чтобы версии миксина не использовались (например, Что касается того, почему __ cmp __ должен был уйти, поскольку у нас были __ lt __ и друзья, зачем использовать другой, другой способ делать то же самое? Это просто мертвый груз в каждой среде выполнения Python (Classic, Jython, IronPython, PyPy, ...). Код, в котором определенно не будет ошибок, это код, которого там нет. Отсюда принцип Python, согласно которому в идеале должен быть один очевидный способ выполнения задачи (в C тот же принцип в " Дух C »стандарта ISO, кстати).

Это не означает, что мы изо всех сил стараемся запрещать вещи (например, почти эквивалентность между миксинами и декораторами классов для некоторых целей), но это определенно означает, что мы не Мне нравится переносить код в компиляторах и / или средах выполнения, который существует избыточно только для поддержки нескольких эквивалентных подходов для выполнения одной и той же задачи.

Дальнейшее редактирование: на самом деле существует даже лучший способ обеспечить сравнение и хеширование для многих классов, включая это в вопросе - метод __ key __ , как я упоминал в своем комментарии к вопросу. Так как я так и не успел написать для него PEP, вы должны реализовать его с помощью Mixin (& c), если он вам нравится:

class KeyedMixin:
  def __lt__(self, other):
    return self.__key__() < other.__key__()
  # and so on for other comparators, as above, plus:
  def __hash__(self):
    return hash(self.__key__())

Это очень распространенный случай, когда сравнение экземпляра с другими экземплярами сводится к сравнению кортежа для каждого с несколькими полями - и тогда хеширование должно быть реализовано на той же основе. Специальный метод __ key __ обращается напрямую к нужным адресатам.

На самом деле это даже лучший способ обеспечить сравнение и хеширование для многих классов, включая тот, который указан в вопросе - метод __ key __ , как я упоминал в своем комментарии к вопросу. Так как я так и не успел написать для него PEP, вы должны реализовать его с помощью Mixin (& c), если он вам нравится:

class KeyedMixin:
  def __lt__(self, other):
    return self.__key__() < other.__key__()
  # and so on for other comparators, as above, plus:
  def __hash__(self):
    return hash(self.__key__())

Это очень распространенный случай, когда сравнение экземпляра с другими экземплярами сводится к сравнению кортежа для каждого с несколькими полями - и тогда хеширование должно быть реализовано на той же основе. Специальный метод __ key __ обращается напрямую к нужным адресатам.

На самом деле это даже лучший способ обеспечить сравнение и хеширование для многих классов, включая тот, который указан в вопросе - метод __ key __ , как я упоминал в своем комментарии к вопросу. Так как я так и не успел написать для него PEP, вы должны реализовать его с помощью Mixin (& c), если он вам нравится:

class KeyedMixin:
  def __lt__(self, other):
    return self.__key__() < other.__key__()
  # and so on for other comparators, as above, plus:
  def __hash__(self):
    return hash(self.__key__())

Это очень распространенный случай, когда сравнение экземпляра с другими экземплярами сводится к сравнению кортежа для каждого с несколькими полями - и тогда хеширование должно быть реализовано на той же основе. Специальный метод __ key __ обращается напрямую к нужным адресатам.

в настоящее время вы должны реализовать его с помощью Mixin (& c), если он вам нравится:

class KeyedMixin:
  def __lt__(self, other):
    return self.__key__() < other.__key__()
  # and so on for other comparators, as above, plus:
  def __hash__(self):
    return hash(self.__key__())

Это очень распространенный случай, когда сравнение экземпляра с другими экземплярами сводится к сравнению кортежа для каждого с несколькими полями - а затем хешированием должны реализовываться на точно такой же основе. Специальный метод __ key __ обращается напрямую к нужным адресатам.

в настоящее время вы должны реализовать его с помощью Mixin (& c), если он вам нравится:

class KeyedMixin:
  def __lt__(self, other):
    return self.__key__() < other.__key__()
  # and so on for other comparators, as above, plus:
  def __hash__(self):
    return hash(self.__key__())

Это очень распространенный случай, когда сравнение экземпляра с другими экземплярами сводится к сравнению кортежа для каждого с несколькими полями - а затем хешированием должны реализовываться на точно такой же основе. Специальный метод __ key __ обращается напрямую к нужным адресатам.

87
ответ дан 24 November 2019 в 05:52
поделиться

Это покрывается PEP 207 - Rich Comparisons

Кроме того, __ cmp __ исчезает в python 3.0. (Обратите внимание, что его нет на http://docs.python.org/3.0/reference/datamodel.html , но он НАХОДИТСЯ на http://docs.python.org/2.7/ ссылка / datamodel.html )

9
ответ дан 24 November 2019 в 05:52
поделиться
Другие вопросы по тегам:

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