__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__, а декоратор сгенерирует остальные на основе этих двух. Однако, если вам нужна более специфическая или оптимизированная реализация каждого оператора, лучше переопределить их все вручную.