Operator Overloading in Python

Operator Overloading is the phenomenon of giving alternate/different meaning to an action performed by an operator beyond their predefined operational function. Operator overloading is also called Operator Ad-hoc Polymorphism.

Python operators work for built-in classes. But the same operator expresses differently with different types. For example, The + operator will perform arithmetic addition on two numbers, merge two lists and concatenate two strings. Python allows the same operator to have different meanings according to the referring context.


Example: Depicting different use of basic arithmetic operators

# Program to show use of 
# + operator for different purposes. 
  
print(5 + 5) 
  
# concatenate two strings 

print("Safa"+"Mulani")  
  
# Product two numbers 
print(10 * 10) 
  
# Repeat the String 
print("Safa"*4) 

Output:

10
SafaMulani
100
SafaSafaSafaSafa

How to overload an operator in python?

To perform operator overloading, Python provides some special function or magic function that is automatically invoked when it is associated with that particular operator. For example, when we use + operator, the magic method __add__ is automatically invoked in which the operation for + operator is defined.


Special Functions in Python

Global functions that begin with double underscore __ are called special functions in Python. It’s because they are not ordinary. The __init__() function which we usually define and resemble as a constructor is one of them. It gets called every time we create a new object of that class.


Magic Methods for Binary Operators in Python

OPERATORMAGIC METHOD
+__add__(self, other)
__sub__(self, other)
*__mul__(self, other)
/__truediv__(self, other)
//__floordiv__(self, other)
%__mod__(self, other)
**__pow__(self, other)

Magic Methods for Comparison Operators in Python

OPERATORMAGIC METHOD
<__lt__(self, other)
>__gt__(self, other)
<=__le__(self, other)
>=__ge__(self, other)
==__eq__(self, other)
!=__ne__(self, other)

Magic Methods for Assignment Operators in Python

OPERATORMAGIC METHOD
-=__isub__(self, other)
+=__iadd__(self, other)
*=__imul__(self, other)
/=__idiv__(self, other)
//=__ifloordiv__(self, other)
%=__imod__(self, other)
**=__ipow__(self, other)

Magic Methods for Unary Operators

OPERATORMAGIC METHOD
__neg__(self, other)
+__pos__(self, other)
~__invert__(self, other)

Example: Overloading binary + operator in Python

When we use + operator, the magic method __add__ is automatically invoked in which the operation for + operator is defined. Hence by changing the magic method’s code, we can give alternative meaning to the + operator.

  
# Program to overload an binary + operator 
  
class X: 
    def __init__(self, x): 
        self.x = x 
  
    # adding two objects  
    def __add__(self, y): 
        return self.x + y.x 
ob1 = X(5) 
ob2 = X(5) 
ob3 = X("Safa") 
ob4 = X("Mulani") 
  
print(ob1 + ob2) # simple addition of objects
print(ob3 + ob4) # concatenation of strings through object addition

Output:

10
SafaMulani

Example: Overloading comparison operators in Python

class X: 
    def __init__(self, x): 
        self.x = x 
    def __lt__(self, other): # Overloading < operator
        if(self.x<other.x): 
            return "ob1 is less than ob2"
        else: 
            return "ob2 is less than ob1"
    def __eq__(self, other): 
        if(self.x == other.x): # Overloading == operator
            return "Both are equal"
        else: 
            return "Not equal"
                  
ob1 = X(2) 
ob2 = X(3) 
print(ob1 < ob2) 
  
ob3 = X(4) 
ob4 = X(4) 
print(ob1 == ob2) 

Output:

ob1 is less than ob2
Not equal

Example: Sample Operator Overloading Program

class Animal:

    def __init__(self, age):
        self.__age = age

    def setage(self, age):
        self.__age = age
 
    def getage(self):
        return self.__age


    def __add__(self, predict):
        return Animal( self.__age + predict.__age )

    def __gt__(self, predict):
        return self.__age > predict.__age

    def __lt__(self, predict):
        return self.__age < predict.__age

    def __str__(self):
        return "Animal with original age " + str(self.__age)

c1 = Animal(5)
print(c1.getage())

c2 = Animal(5)
print(c2.getage())

c3 = c1 + c2
print(c3.getage())

print( c3 > c2) 

print( c1 < c2) 

print(c3) 

Output:

5                                                                                                                                             
5                                                                                                                                             
10                                                                                                                                            
True                                                                                                                                          
False                                                                                                                                         
Animal with original age 10      

References

  • Python Operator Overloading
  • Python Comparison Operators