__eq__(self, other): Определяет равенство (==).__ne__(self, other): Определяет неравенство (!=).__lt__(self, other): Определяет "меньше чем" (<).__gt__(self, other): Определяет "больше чем" (>).__le__(self, other): Определяет "меньше или равно" (<=).__ge__(self, other): Определяет "больше или равно" (>=).__eq__ обычно требует переопределения __hash__, чтобы обеспечить корректную работу с хеш-таблицами (например, в словарях и множествах).
Изменить поведение сравнения объектов по умолчанию в Python можно путем переопределения специальных (магических) методов класса, связанных с операторами сравнения. Вот основные методы:
__eq__(self, other): Определяет поведение оператора == (равно). Возвращает True если объекты равны, иначе False.__ne__(self, other): Определяет поведение оператора != (не равно). Возвращает True если объекты не равны, иначе False. По умолчанию возвращает результат, противоположный __eq__.__lt__(self, other): Определяет поведение оператора < (меньше). Возвращает True если self меньше other, иначе False.__le__(self, other): Определяет поведение оператора <= (меньше или равно). Возвращает True если self меньше или равно other, иначе False.__gt__(self, other): Определяет поведение оператора > (больше). Возвращает True если self больше other, иначе False.__ge__(self, other): Определяет поведение оператора >= (больше или равно). Возвращает True если self больше или равно other, иначе False.Важные моменты:
__eq__, __ne__, __lt__, __le__, __gt__, __ge__) для обеспечения консистентного и предсказуемого поведения. Если реализован только один, остальные могут работать непредсказуемо.other. Нужно предусмотреть обработку ситуаций, когда other не является экземпляром класса self. Часто полезно возвращать NotImplemented, чтобы Python попробовал вызвать оператор с аргументами в обратном порядке (other.__eq__(self)).__eq__, то обязательно нужно переопределить __hash__, чтобы объекты, которые считаются равными, имели одинаковые хэш-значения. Это важно для корректной работы со структурами данных, такими как словари и множества. Если __eq__ переопределен, а __hash__ нет, Python автоматически установит __hash__ = None, что сделает объекты не хэшируемыми.functools.total_ordering: Можно упростить реализацию методов сравнения с помощью декоратора functools.total_ordering. Если реализованы __eq__ и еще один из методов сравнения (например, __lt__), декоратор автоматически сгенерирует остальные методы. Это может сделать код более читаемым и менее подверженным ошибкам.Пример:
from functools import total_ordering
@total_ordering
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __eq__(self, other):
if not isinstance(other, Point):
return NotImplemented
return self.x == other.x and self.y == other.y
def __lt__(self, other):
if not isinstance(other, Point):
return NotImplemented
return self.x < other.x or (self.x == other.x and self.y < other.y)
def __hash__(self):
return hash((self.x, self.y))
p1 = Point(1, 2)
p2 = Point(1, 2)
p3 = Point(2, 1)
print(p1 == p2) # True
print(p1 != p3) # True
print(p1 < p3) # True
print(p1 > p3) # False
print(p1 <= p2) # True
В этом примере класс Point переопределяет __eq__, __lt__ и __hash__, а functools.total_ordering генерирует остальные методы сравнения. Это позволяет сравнивать экземпляры класса Point по их координатам.