When you’ve learned object-oriented programming and you are trying to perform some mathematical calculations on the objects you’ve created from a class, you probably get an error telling you this is not possible which will lead us to use the python operators overloading.

Python makes it easy to perform mathematical operations, such as adding, subtracting, or multiplying numbers using the mathematics signs. Still, the problem arises when you learn object-oriented programming, and you want to add two objects (instances) created under the same class.

Python developers have created magic functions or the under methods to solve this problem. They’ve come up with some built-in functions to tell python that these signs are mathematics signs and you need to perform mathematical calculations on these objects. Let’s make two instances and try to make some mathematical calculations on them:

``````#Creating the class
class Book:

#Initaiting the method
def __init__(self, price):
self.price = price

#Creating the objects
b1 = Book(30)
b2 = Book(50)

#Printing the result
print(b1 + b2)``````

You will have an error after running this code. The python interpreter didn’t recognize what that plus sign means in mathematics since it is not implemented directly into the object-oriented type of programming, so we will need to use the magic functions.

### 2. Python Magic Functions

You may think that the magic functions or you can call them special functions, or the dunder methods are the same functions you created to make things easier in the development, but they are built-in python and only used inside the python classes.

The previous example used “__init__” and always starts and ends with the “__” double scores. We will use another in this example but let’s first print the values of the objects and see what we will get:

``````#Creating the class
class Book:

#Initaiting the method
def __init__(self, price):
self.price = price

#Creating the objects
b1 = Book(30)
b2 = Book(50)

#Printing the objects values
print(b1)
print(b2)``````

The previous code will show you the memory locations (RAM) where the values are stored. It doesn’t show the actual prices like when you print a value in python. Let’s now fix this problem by using a magic function:

``````#Creating the class
class Book:

#Initaiting the method
def __init__(self, price):
self.price = price

#Return the price information
def __str__(self):
return "{}".format(self.price)

#Creating the objects
b1 = Book(30)
b2 = Book(50)

#Printing the objects values
print(b1)
print(b2)``````

It will print the values of these two books after you run the previous code, and by using the “__str__” magic method, it will give you the actual price of these objects you’ve set. You can now perform the mathematics operations on these two objects by this way:

``````#Creating the class
class Book:

#Initaiting the method
def __init__(self, price):
self.price = price

#Return the price information
def __str__(self):
return "{}".format(self.price)

#Creating the objects
b1 = Book(30)
b2 = Book(50)

#Printing the sum of the two books
print(b1.price + b2.price)``````

You will get the sum of these two books’ prices which is 80, but this is not the right and friendly way to perform mathematical calculations on the objects, and that’s why we are going to use the magic methods created specifically for performing these operations.

There is a magic method explicitly created for every mathematical operation, such as adding & subtracting. For now, we will use the add method in this example:

``````#Creating the class
class Book:

#Initaiting the method
def __init__(self, price):
self.price = price

#Sum the price
return self.price + other.price

#Creating the objects
b1 = Book(30)
b2 = Book(50)

#Printing the sum of the two books
print(b1 + b2)``````

You will have the same result as the previous example. We’ve used the “__add__” magic method for performing this adding calculation.

This magic function accepts two arguments The first one is self which means the first price you use in your calculation, followed by the other argument, which represents any different number you will add. Let’s now try another magic method:

``````#Creating the class
class Book:

#Initaiting the method
def __init__(self, price):
self.price = price

#Subtract the price
def __sub__(self, other):
return self.price - other.price

#Creating the objects
b1 = Book(30)
b2 = Book(50)

#Printing the subtraction of the two books
print(b2 - b1)``````

You will get the subtraction of these two prices, which is 20. We’ve used the “__sub__” for performing the subtraction of these two prices. Everything is the exact thing meaning self is the current price, and the other is represents any different price. Let’s see another one:

``````#Creating the class
class Book:

#Initaiting the method
def __init__(self, price):
self.price = price

#Multiplying the price
def __mul__(self, other):
return self.price * other.price

#Creating the objects
b1 = Book(30)
b2 = Book(50)

#Printing the Multiplication of the two books
print(b2 * b1)``````

We’ve used the “__mul__” magic function to multiply the two books prices. The result will be 1500. There are also many other magic methods for calculation, such as division:

``````#Creating the class
class Book:

#Initaiting the method
def __init__(self, price):
self.price = price

#MCalculate the division of the prices
def __truediv__(self, other):
return self.price / other.price

#Creating the objects
b1 = Book(30)
b2 = Book(60)

#Printing the division of the two books
print(b2 / b1)``````

You can see that “__truediv__” is used to calculate these two prices’ divisions.