У меня есть простой класс Python, который я хочу сравнить. Итак, я реализовал операторы сравнения. Затем я понял, что делаю то же самое для очень многих классов, и это очень похоже на дублирование кода.
class Foo(object):
def __init__(self, index, data):
self.index = index
self.data = data
def __lt__(self, other):
return self.index < other.index
def __gt__(self, other):
return self.index > other.index
def __le__(self, other):
return self.index <= other.index
def __ge__(self, other):
return self.index >= other.index
def __eq__(self, other):
return self.index == other.index
def __ne__(self, other):
return self.index != other.index
Поэтому я думаю, что простое решение будет примерно таким:
class Comparable(object):
def _compare(self, other):
raise UnimplementedError()
def __lt__(self, other):
return self._compare(other) < 0
def __gt__(self, other):
return self._compare(other) > 0
def __le__(self, other):
return self._compare(other) <= 0
def __ge__(self, other):
return self._compare(other) >= 0
def __eq__(self, other):
return self._compare(other) == 0
def __ne__(self, other):
return self._compare(other) != 0
class Foo1(Comparable):
def _compare(self, other):
return self.index - other.index
class Foo2(Comparable):
def _compare(self, other):
# ...
class Foo3(Comparable):
def _compare(self, other):
# ...
Но это кажется настолько простым, что я чувствую, что изобретаю велосипед здесь.
Мне интересно, есть ли более «естественный» способ добиться этого.
@Jkdc «Специальный метод __cmp__()
больше не поддерживается в Python 3.»
@Jkdc Это именно то, что я искал! Жалко для поддержки Python 3 :(
Вы можете использовать PY3__cmp__ класс миксина
Как описано в документах, вы можете использовать functools.total_ordering
, чтобы сохранить некоторый шаблон при написании всех сравнений.
To avoid the hassle of providing all six functions, you can implement
__eq__
,__ne__
, and only one of the ordering operators, and use thefunctools.total_ordering()
decorator to fill in the rest.
Чтобы быть точным, они имеют в виду шесть функций: __eq__
, __ne__
, __lt__
, __le__
, __gt__
и __ge__
.
Итак, вам нужна автоматизация при создании методов богатое сравнение. Вы можете получить такое поведение, используя функцию высшего порядка functools.total_ordering()
. Подробнее см. Справка.
Для чего-то такого базового вы можете просто реализовать
__cmp__
вместо каждой отдельной операции.