Modules -> OOP -> Dunder methods -> Comparing methods

Comparing methods


Related code
class Dog:
    """Represents a dog.

    attributes: name: str, age: int, energy: int
    """

    def __init__(self, name, age, energy):
        self.name = name
        self.age = age
        self.energy = energy

    def __str__(self):
        return f'Name: {self.name}, Age: {self.age}'

    def is_older(self, other):
        return self.age > other.age

murki = Dog("Murki", 2, 50)
reksi = Dog("Reksi", 1, 50)

Instead of using is_older to see if a dog is older than the other, it would be better if we could do dog1 > dog2. Let's try to apply > two murki and reksi:

>>> murki > reksi
TypeError("'>' not supported between instances of 'Dog' and 'Dog'")

Python doesn't know how to compare them, we have to tell Python how it should compare two dogs, just like we told is_older method.

In order to be able to apply relational operators to dogs we have to overload the following dunder methods:

  • __gt__ (greater than)
  • __gte__ (greater than or equal)
  • __lt__ (less than)
  • __lte__ (less than or equal)
  • __eq__ (equal to)
class Dog:
    ...
    def __gt__(self, other):
        return "__gt__ method is activated"
...

Now whenever we apply > to two dogs, this method is activated:

>>> murki > reksi
__gt__ method is activated

We proved that __gt__ is activated when we apply > to two dogs.

Now let's give meaning to greater than in the case of comparing dogs. Let's say a dog is greater than the other if it is older. So, let's return True if the first dog is older than the other, and False otherwise.

class Dog:
    ...
    def __gt__(self, other):
        return self.age > other.age
...
>>> murki > reksi
True

Now most of the other comparisons (less than, equal to, ...) can be derived from __gt__:

>>> murki < reksi
False
>>> murki == reksi
False

But if we want to explicitly program those operators, we can do so:

class Dog:
    ...
    def __gt__(self, other):
        return self.age > other.age

    def __gte__(self, other):
        return self.age >= other.age

    def __lt__(self, other):
        return self.age < other.age

    def __lte__(self, other):
        return self.age >= other.age

    def __eq__(self, other):
        return self.age == other.age

    def __ne__(self, other):
        return self.age != other.age
...