Learnerslesson
   JAVA   
  SPRING  
  SPRINGBOOT  
 HIBERNATE 
  HADOOP  
   HIVE   
   ALGORITHMS   
   PYTHON   
   GO   
   KOTLIN   
   C#   
   RUBY   
   C++   




PYTHON - OPERATOR OVERLOADING


We have already seen that the '+' operatior is used to add to numbers.


Example :


x = 5
y = 7
z = x + y
print("The added result is :",z)


Output :



  The added result is : 12

That was quite easy.


Now, let us say, we have a class that has an integer value. And we want to create two objects and add them.


Let me make it a little simpler with the below example.


Example :


class MyClass:
    def __init__(self, x):
        self.x = x
		
obj1 = MyClass(5)
obj2 = MyClass(7)
obj3 = obj1 + obj2
print("The added result",obj3)


Output :



  obj3 = obj1 + obj2
TypeError: unsupported operand type(s) for +: 'MyClass' and 'MyClass'

So, in the above code, we have created a class named 'MyClass' that has an attribute named 'x'.


And we have defined a Constructor that initialises the attribute 'x'.


def __init__(self, x):
    self.x = x

Then we have created an object 'obj1' of the class 'MyClass'.


obj1 = MyClass(5)

And initialised the value of 'x' with '5'(For object 'obj1').


Operator Overloading

Similarly, we have created a second object 'obj2'.


obj2 = MyClass(7)

And initialised the value of 'x' with '7'(For object 'obj2').


java_Collections

Now, we tried to add two objects 'obj1' and 'obj2'. Just to add '5' and '7'.


obj3 = obj1 + obj2

But we end up with the below error.


TypeError: unsupported operand type(s) for +: 'MyClass' and 'MyClass'

This is because Python is confused that how can adding two objects add their values?


With this we come to the concept of Overloading the operators. i.e. We will make the '+' operator act the waty, we want it to act.


Let us modify the above example.


Example :


class MyClass:
    def __init__(self, x):
        self.x = x
		
    def __add__(self,obj):
        return self.x + obj.x
		
obj1 = MyClass(5)
obj2 = MyClass(7)
obj3 = obj1 + obj2
print("The added result",obj3)


Output :



  The added result 12

And all we have done is, defined a method called 'def __add__(self,obj):'.


def __add__(self,obj):
    return self.x + obj.x

This '__add__( )' method is already defined by Python.


And all we are doing is, redefining the '__add__( )' method. So that it works exactly the way we want it to work.


So, the 'def __add__(self,obj):' has two parameters, 'self' and 'obj'.


Now, the '__add__( )' method gets called when the below statement executes.


obj3 = obj1 + obj2

And what happens is, the value of the object, 'obj1' is assigned to 'self' and 'obj2' is assigned to 'obj'.


java_Collections

And right now, 'self' has the contents of 'obj1',


java_Collections

And 'obj' has the contents of 'obj2',


java_Collections

Now, since, the '__add__( )' method has the contents,


def __add__(self,obj):
    return self.x + obj.x

The 'return' statement,


return self.x + obj.x

Adds the value of 'self.x' i.e. '5' and 'obj.x' i.e. '7'.


And the added value is returned to 'obj3'.


obj3 = obj1 + obj2

java_Collections

So, the print statement,


print("The added result",obj3)

Prints the value of 'x' from the object 'obj3'. And we get the below output.


The added result 12

But have you thought, when we are executing the statement,


obj3 = obj1 + obj2

How come the 'def __add__(self,obj):' gets called?


This is because, for every operator, be it a '+' or '-' or any other operator, Python uses a method for each. And each method begins with double underscore '__' and ends with double underscore '__' followed by the name.


So, for '+', Python has the 'def __add__(self,obj):' method already defined. And all we are doing is, redefining the 'def __add__(self,obj):' in our class.


class MyClass:
    def __init__(self, x):
        self.x = x
		
    def __add__(self,obj):
        return self.x + obj.x

So, when Python finds the '+' operator for the objects of the class 'MyClass'.


obj3 = obj1 + obj2

At first, it searches for the 'def __add__(self,obj):' in the class 'MyClass'. And when it finds it.


	def __add__(self,obj):
		return self.x + obj.x

It executes the task.


Similarly, Python has other methods for other operators as well. Let us see them below:



Operator Expression Overloaded Method
Addition p1 + p2 def __add__(self,obj)
Subtraction p1 - p2 def __sub__(self,obj)
Division p1 / p2 def __truediv__(self,obj)
Multiplication p1 * p2 def __mul__(self,obj)
Floor Division p1 // p2 def __floordiv__(self,obj)
Modulo p1 % p2 def __mod__(self,obj)
Power p1 ** p2 def __pow__(self,obj)
Right Shift p1 >> p2 def __rshift__(self,obj)
Left Shift p1 << p2 def __lshift__(self,obj)
AND p1 & p2 def __and__(self,obj)
OR p1 | p2 def __or__(self,obj)
XOR p1 ^ p2 def __xor__(self,obj)
NOT ~p1 def __invert__(self,obj)
Equal to p1 == p2 def __eq__(self,obj)
Not equal to p1 != p2 def __ne__(self,obj))
Greater than p1 > p2 def __ne__(self,obj)
Greater than or equal to p1 >= p2 def __ge__(self,obj)
Less than p1 < p2 def __lt__(self,obj)
Less than or equal to p1 <= p2 def __le__(self,obj)

So, if you want to overload, any of the above operators and customise it your way. You can use the corresponding overloaded method for it.