Sobes.tech
Middle

What are the methods __eq__, __ne__, __lt__, __le__, __gt__, and __ge__ in Python and how are they used?

sobes.tech AI

Answer from AI

These methods define the behavior of objects during comparison. They are called "rich comparison methods".

  • __eq__(self, other): Defines the behavior of the == operator (equality). Returns True if objects are equal, otherwise False.
  • __ne__(self, other): Defines the behavior of the != operator (inequality). By default, if __eq__ is defined, then __ne__ is its logical negation.
  • __lt__(self, other): Defines the behavior of the < operator (less than). Returns True if self is less than other, otherwise False.
  • __le__(self, other): Defines the behavior of the <= operator (less than or equal). By default, if __lt__ or __eq__ are defined, it can be automatically computed.
  • __gt__(self, other): Defines the behavior of the > operator (greater than). Returns True if self is greater than other, otherwise False.
  • __ge__(self, other): Defines the behavior of the >= operator (greater than or equal). By default, if __gt__ or __eq__ are defined, it can be automatically computed.

Defining these methods in user-defined classes allows comparing class instances using standard comparison operators.

Example usage:

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

    def __eq__(self, other):
        # Compare by name and age
        if isinstance(other, Person):
            return self.name == other.name and self.age == other.age
        return False

    def __lt__(self, other):
        # Compare by age
        if isinstance(other, Person):
            return self.age < other.age
        return NotImplemented  # Indicates that comparison is not supported with this type

    def __gt__(self, other):
        # Compare by age (reverse of <)
        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 (uses __eq__)
print(p1 == p3)  # False
print(p1 != p3)  # True (uses __ne__, which is based on __eq__)
print(p1 < p3)   # False (uses __lt__)
print(p3 < p1)   # True
print(p1 > p3)   # True (uses __gt__)

It is recommended to define __eq__ and, if ordered comparison is needed, __lt__. Other methods (__ne__, __le__, __gt__, __ge__) can be automatically added using the @functools.total_ordering decorator from the functools module, provided that __eq__ and at least one of <, <=, >, >= are defined.

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 (automatically computed thanks to @total_ordering)
print(p4 <= p5)  # False