__eq__(self, other)
: Определяет поведение оператора `==` (равно).__ne__(self, other)
: Определяет поведение оператора `!=` (не равно).__lt__(self, other)
: Определяет поведение оператора `<` (меньше).__gt__(self, other)
: Определяет поведение оператора `>` (больше).__le__(self, other)
: Определяет поведение оператора `<=` (меньше или равно).__ge__(self, other)
: Определяет поведение оператора `>=` (больше или равно).
class MyClass:
def __init__(self, value):
self.value = value
def __eq__(self, other):
if isinstance(other, MyClass):
return self.value == other.value
return False
def __lt__(self, other):
if isinstance(other, MyClass):
return self.value < other.value
return NotImplemented
Важно: Если определить только `__eq__`, рекомендуется также определить `__ne__`. Если определить один из методов `__lt__`, `__gt__`, `__le__`, `__ge__`, рассмотрите возможность использования декоратора `functools.total_ordering`, чтобы автоматически сгенерировать остальные.
Переопределение операторов сравнения в Python позволяет нам определить, как объекты нашего класса должны сравниваться друг с другом с использованием стандартных операторов: ==
(равно), !=
(не равно), <
(меньше), >
(больше), <=
(меньше или равно), и >=
(больше или равно).
Для этого используются специальные методы (magic methods или dunder methods), имена которых соответствуют операторам:
__eq__(self, other)
: Реализует оператор ==
(равно). Должен возвращать True
, если self
и other
равны, и False
в противном случае.__ne__(self, other)
: Реализует оператор !=
(не равно). Должен возвращать True
, если self
и other
не равны, и False
в противном случае. Часто (но не всегда) реализация может быть просто возвращением not (self == other)
.__lt__(self, other)
: Реализует оператор <
(меньше). Должен возвращать True
, если self
меньше other
, и False
в противном случае.__gt__(self, other)
: Реализует оператор >
(больше). Должен возвращать True
, если self
больше other
, и False
в противном случае.__le__(self, other)
: Реализует оператор <=
(меньше или равно). Должен возвращать True
, если self
меньше или равен other
, и False
в противном случае.__ge__(self, other)
: Реализует оператор >=
(больше или равно). Должен возвращать True
, если self
больше или равен other
, и False
в противном случае.Пример:
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __eq__(self, other):
if isinstance(other, Point):
return self.x == other.x and self.y == other.y
return False # Сравнение с объектом другого типа
def __ne__(self, other):
return not self.__eq__(other)
def __lt__(self, other):
if isinstance(other, Point):
return (self.x**2 + self.y**2) < (other.x**2 + other.y**2)
return NotImplemented # Сигнализируем, что сравнение с объектом другого типа не поддерживается
def __gt__(self, other):
if isinstance(other, Point):
return (self.x**2 + self.y**2) > (other.x**2 + other.y**2)
return NotImplemented
def __le__(self, other):
return self.__lt__(other) or self.__eq__(other)
def __ge__(self, other):
return self.__gt__(other) or self.__eq__(other)
#Примеры использования
point1 = Point(1, 2)
point2 = Point(1, 2)
point3 = Point(3, 4)
print(point1 == point2) # Вывод: True
print(point1 != point3) # Вывод: True
print(point1 < point3) # Вывод: True
print(point1 > point3) # Вывод: False
print(point1 <= point2) # Вывод: True
print(point1 >= point3) # Вывод: False
print(point1 == "string") # Вывод: False
print(point1 < "string") # Вывод: TypeError: '<' not supported between instances of 'Point' and 'str'
Важные моменты:
True
или False
), за исключением случаев, когда сравнение не имеет смысла (например, сравнение объекта с объектом другого, несовместимого типа). В таких случаях можно (и рекомендуется) возвращать NotImplemented
. Это позволяет Python попытаться выполнить сравнение, вызвав соответствующий метод у другого объекта (other
). Если ни один из объектов не реализует корректное сравнение, будет вызвано исключение TypeError
.x == x
должно быть всегда True
), транзитивность (если x == y
и y == z
, то x == z
), и согласованность (результат сравнения не должен меняться со временем, если значения сравниваемых объектов не меняются).functools.total_ordering
: Декоратор @functools.total_ordering
(из модуля functools
) может упростить определение всех операторов сравнения. Достаточно определить __eq__
и один из __lt__
, __le__
, __gt__
, __ge__
, а декоратор сгенерирует остальные на основе этих двух. Однако, если вам нужна более специфическая или оптимизированная реализация каждого оператора, лучше переопределить их все вручную.