Day 14 - Operator Overloading

Every day we write multiple lines of code, comparing values or performing calculations similar to this one:

print(15 > 20)
print(36 - 23)

# Output:
# False
# 13

Usually, we think about comparing or making numerical calculations since it is something basic that we know since we were children, but this type of comparison can be performed with any class using some magic methods.

For now we will create a Product class with some of its basic attributes:

class Product:
    def __init__(self, name, price):
        self.__name = name
        self.__price = price
    
    def __repr__(self):
        return f"Product: {self.__name}"

pizza = Product("pizza", 5)
hotdog = Product("hotdog", 1)

print(pizza)
print(hotdog)

# Output:
# Product: pizza
# Product: hotdog

Two instances of the Product class were created, what about trying to compare them.

print(pizza > hotdog)
print(pizza < hotdog)
print(pizza == hotdog)

# Output:
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# TypeError: '>' not supported between instances of 'Product' and 'Product'

At this point it is not possible to compare these instances, in fact it is not known what we are comparing, to fix this we will add some magic methods.

class Product:
    def __init__(self, name, price):
        self.__name = name
        self.__price = price
    
    def __repr__(self):
        return f"Product: {self.__name}"
    
    def __lt__(self, other_instance):
        return self.__price < other_instance.__price
    
    def __gt__(self, other_instance):
        return self.__price > other_instance.__price
    
    def __eq__(self, other_instance):
        return self.__price == other_instance.__price

pizza = Product("pizza", 5)
hotdog = Product("hotdog", 1)

Let’s try again to make the comparisons.

print(pizza > hotdog)
print(pizza < hotdog)
print(pizza == hotdog)

# Output:
# True
# False
# False

These magic methods allow us to compare our items, in my case I had their prices compared, however, you can define these methods as you need them.

These methods receive as an argument another one, which is related to the value with which we are going to make the comparison.

Operations

It is possible to perform operations between different objects, what about knowing the total of an order? why not add up each of these products and get the total.

More info

class Product:
    def __init__(self, name, price):
        self.__name = name
        self.__price = price
    
    def __repr__(self):
        return f"Product: {self.__name}"
    
    def __add__(self, other_instance):
        return self.__price + other_instance.__price

pizza = Product("pizza", 5)
hotdog = Product("hotdog", 1)

total = pizza + hotdog
print(total)

# Output:
# 6

Go to the Challenge

Go to the Solution