Python Object & Class

Python Operator Overloading

You’ve probably wondered why the same built-in operator or function behaves differently for objects of different classes. This is known as Python operator overloading or Python function overloading. For example, the operator ‘+‘ can be used to add two integers, join two strings, or merge two lists. It is possible since the ‘+’ operator is overloaded by the int and str classes. Let us understand this by looking at an example below,

                    

# Add 2 integer values
a = 1 + 6
print(a)

# Concatenate 2 strings
a = 'Python' + 'Program'
print(a)

# Concatenate 2 lists
a = ['A', 'B'] + [1, 2, 3]
print(a)

Output

                    

7
PythonProgram
['A', 'B', 1, 2, 3]

Python operator overloading refers to a single operator’s capacity to perform several operations based on the class (type) of operands. The following article will teach you how to use operator overloading in Python Object-Oriented Programming.

Python Operator Overloading

The phenomenon of adding alternate/different meaning to an action done by an operator beyond their predefined operational role is known as operator overloading. Operator Ad-hoc Polymorphism is another name for Python operator overloading.

The process of utilizing an operator in different ways depending on the operands is known as operator overloading. In Python, you can change how an operator behaves with different data types. The operators are methods defined in their respective classes. Operator overloading is the process of defining methods for operators.

So, what happens when we utilize them with user-defined class objects? Consider the following class, which attempts to replicate a point in a two-dimensional coordinate system.

Example

                    

class Circle:
    def __init__(self, radius):
        self.__radius = radius

c1 = Circle(2)
c2 = Circle(8)
c3 = c1 + c2
print(c3)

Output

                    

Traceback (most recent call last):
  File "", line 9, in 
TypeError: unsupported operand type(s) for +: 'Circle' and 'Circle'

We can see that a TypeError was triggered because Python didn’t know how to combine two Circle objects. However, we may accomplish this work in Python by using operator overloading. But first, let’s talk about special functions.

Advantages of Python Operator Overloading

  • It allows for reusability; instead of developing numerous methods with minor differences, we can simply write one method and overload it.
  • It also increases code clarity and reduces complexity.
  • Operator overloading also makes the code more concise and easier to understand.

Python Special Functions

In Python, class functions or global functions that begin with a double underscore are referred to be special functions. It’s because they’re not like everyone else. One of these is the __init__() function we defined before. It is invoked whenever a new object of that class is created. Python has a plethora of other special functions.

We can make our class compatible with built-in functions by using custom functions.

                    

>>>c1 = Circle(5)
>>>print(c1)
<__main__.Circle object at 0x7f5146eed4c0>

Assume we want the print() function to print the Radius of the Circle object of what we got. In our class, we may define a __str__() function that determines how the object is printed. Let’s have a look at how we can accomplish this:

                    

class Circle:
    def __init__(self, radius):
        self.radius = radius
 
    def __str__(self):
        return 'Radius of the circle is: {}'.format(self.radius)

c1 = Circle(5)
print(c1)

Output

                    

Radius of the circle is: 5

It turns out that whether we utilize the built-in functions str() or format(), the identical technique is invoked.

                    

>>>print(str(c1))
Radius of the circle is: 5

>>>print(format(c1))
Radius of the circle is: 5

When you use str(c1) or format(c1), Python calls the c1.__str__() method internally. As a result, the term “special functions” was coined.

Overloading the + Operator

Consider the following scenario: we have two objects that are physical representations of a class (user-defined data type). If we try to add two objects using the binary ‘+’ operator, the compiler throws an error since the compiler does not know how to add two objects. So we define a method for an operator, which is referred to as operator overloading. We can overload all existing operators but not build new ones. The method’s name should start and conclude with a double underscore (__).

To overload the + operator, we must include the __add__() function in the class. Within this function, we can do whatever we want.

Example

                    

class Circle:
    def __init__(self, radius):
        self.radius = radius

    def __str__(self):
        return 'Radius of the circle is: {}'.format(self.radius)

    def __add__(self, other_circle):
        return Circle( self.radius + other_circle.radius )

c1 = Circle(2)
c2 = Circle(6)
c3 = c1 + c2
print(c3)

Output

                    

Radius of the circle is: 8

In the above example, we added the __add__() function, which allows us to use the + operator to combine two circle objects. We create a new object and return it to the caller within the __add__() method. What actually happens is that, when you use c1 + c2, Python calls c1.__add__(c2) which in turn is Circle.__add__(c1,c2). After this, the addition operation is carried out the way we specified.

We can also overload other operators in the same way. The special function that must be implemented is listed below.

Operator Expression Special Function
Addition c1 + c2 c1.__add__(c2)
Subtraction c1 – c2 c1.__sub__(c2)
Multiplication c1 * c2 c1.__mul__(c2)
Power c1 ** c2 c1.__pow__(c2)
Division c1 / c2 c1.__truediv__(c2)
Floor Division c1 // c2 c1.__floordiv__(c2)
Remainder c1 % c2 c1.__mod__(c2)
Bitwise Left Shift c1 << c2 c1.__lshift__(c2)
Bitwise Right Shift c1 >> c2 c1.__rshift__(c2)
Bitwise AND c1 & c2 c1.__and__(c2)
 Bitwise OR c1 | c2 c1.__or__(c2)
Bitwise XOR c1 ^ c2 c1.__xor__(c2)
Bitwise NOT ~c1 c1.__invert__()

Overloading Comparison Operators

Python does not restrict operator overloading to simply arithmetic operators. We can also overload comparison operators. Assume we wanted to use the < symbol in our Circle class. For this reason, let us compare the radius of circles and return the result.

Example

                    

class Circle:
    def __init__(self, radius):
        self.radius = radius

    def __str__(self):
        return 'Radius of the circle is: {}'.format(self.radius)

    def __lt__(self, other):
        cir1 = self.radius
        cir2 = other.radius
        return cir1 < cir2

c1 = Circle(2)
c2 = Circle(6)
c3 = Circle(3)

print(c1<c2)
print(c2<c3)
print(c1<c3)

Output

                    

True
False
True

Similarly, the special functions that must be implemented in order to overload other comparison operators are listed below.

Operator Expression Special Function
Less than c1 < c2 c1.__lt__(c2)
Less than or equal to c1 <= c2 c1.__le__(c2)
Equal to c1 = c2 c1.__eq__(c2)
Not equal to c1 != c2 c1.__ne__(c2)
Greater than c1 > c2 c1.__gt__(c2)
Greater than or equal to c1 >= c2 c1.__ge__(c2)

Frequently Asked Questions

Q1. Is there function overloading in Python?

The ability to have many functions with the same name but distinct signatures/implementations is referred to as function overloading. Function overloading is not supported in Python. When we declare multiple functions with the same name, the latter one always takes precedence over the earlier one, resulting in a single entry in the namespace for each function name.

However, we can implement function overloading in Python by distinguishing functions with the same name by the number of arguments they accept. We can call the function with zero, one, two, or even more parameters, depending on how it is defined. This is known as “function overloading.”

Overloading functions increase code reusability, reduce complexity, and improve code clarity for people who will use or work on it. Overloading functions in Python can be of two types: overloading built-in functions and overloading custom or user-defined functions.

Q2. How do you overload an assignment operator in Python?

Python provides a unique function or magic function that is automatically invoked when it is associated with that particular operator to perform assignment operator overloading. When we use the += assignment operator, for example, the magic function __iadd__() is immediately performed, in which the action for the += operator is defined.

Example

                    

# Python program to overload assignment operator
class Coordinates:
    def __init__(self,a, b):
        self.a = a
        self.b = b

    def __str__(self):
        return "({0},{1})".format(self.a,self.b)

    def __iadd__(self, other):
        self.a += other.a
        self.b += other.b
        return Coordinates(self.a,self.b)

obj1 = Coordinates(5,10)
obj2 = Coordinates(2,5)
obj2 += obj1
print(obj2)

Output

Other special functions that must be implemented in order to overload other assignment operators are listed below.

Operator Special Function
+= __iadd__(self, other)
-= __isub__(self, other)
*= __imul__(self, other)
/= __idiv__(self, other)
//= __ifloordiv__(self, other)
%= __imod__(self, other)
**= __ipow__(self, other)
>>= __irshift__(self, other)
<<= __ilshift__(self, other)
&= __iand__(self, other)
|= __ior__(self, other)
^= __ixor__(self, other)

Share with friends

Customize your course in 30 seconds

Which class are you in?
5th
6th
7th
8th
9th
10th
11th
12th
Get ready for all-new Live Classes!
Now learn Live with India's best teachers. Join courses with the best schedule and enjoy fun and interactive classes.
tutor
tutor
Ashhar Firdausi
IIT Roorkee
Biology
tutor
tutor
Dr. Nazma Shaik
VTU
Chemistry
tutor
tutor
Gaurav Tiwari
APJAKTU
Physics
Get Started

Leave a Reply

Your email address will not be published. Required fields are marked *

Download the App

Watch lectures, practise questions and take tests on the go.

Customize your course in 30 seconds

No thanks.