Назад к вопросам
Middle
72
questionbank

Каковы методы __eq__, __ne__, __lt__, __le__, __gt__ и __ge__ в Python и как они используются?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

Эти методы определяют поведение объектов при сравнении. Они называются "богатыми методами сравнения" (rich comparison methods).

  • __eq__(self, other): Определяет поведение оператора == (равенство). Возвращает True, если объекты равны, иначе False.
  • __ne__(self, other): Определяет поведение оператора != (неравенство). По умолчанию, если определен __eq__, то __ne__ является его логическим отрицанием.
  • __lt__(self, other): Определяет поведение оператора < (меньше). Возвращает True, если self меньше other, иначе False.
  • __le__(self, other): Определяет поведение оператора <= (меньше или равно). По умолчанию, если определены __lt__ или __eq__, может быть автоматически вычислен.
  • __gt__(self, other): Определяет поведение оператора > (больше). Возвращает True, если self больше other, иначе False.
  • __ge__(self, other): Определяет поведение оператора >= (больше или равно). По умолчанию, если определены __gt__ или __eq__, может быть автоматически вычислен.

Определение этих методов в пользовательских классах позволяет сравнивать экземпляры класса с помощью стандартных операторов сравнения.

Пример использования:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __eq__(self, other):
        // Сравниваем по имени и возрасту
        if isinstance(other, Person):
            return self.name == other.name and self.age == other.age
        return False

    def __lt__(self, other):
        // Сравниваем по возрасту
        if isinstance(other, Person):
            return self.age < other.age
        return NotImplemented // Указывает, что сравнение не поддерживается с этим типом

    def __gt__(self, other):
        // Сравниваем по возрасту (обратное к <)
        if isinstance(other, Person):
            return self.age > other.age
        return NotImplemented

p1 = Person("Alice", 30)
p2 = Person("Alice", 30)
p3 = Person("Bob", 25)

print(p1 == p2) // True (используется __eq__)
print(p1 == p3) // False
print(p1 != p3) // True (используется __ne__, который основан на __eq__)
print(p1 < p3) // False (используется __lt__)
print(p3 < p1) // True
print(p1 > p3) // True (используется __gt)

Рекомендуется определять __eq__ и, если нужно упорядоченное сравнение, __lt__. Остальные методы (__ne__, __le__, __gt__, __ge__) могут быть автоматически добавлены с помощью декоратора @functools.total_ordering из модуля functools, при условии, что определены __eq__ и хотя бы один из <, <=, >, >=.

import functools

@functools.total_ordering
class AnotherPerson:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __eq__(self, other):
        if isinstance(other, AnotherPerson):
            return self.name == other.name and self.age == other.age
        return False

    def __lt__(self, other):
        if isinstance(other, AnotherPerson):
            return self.age < other.age
        return NotImplemented

p4 = AnotherPerson("Charlie", 40)
p5 = AnotherPerson("David", 35)

print(p4 >= p5) # True (вычислено автоматически благодаря @total_ordering)
print(p4 <= p5) # False