Operator Overloading in Python with Example

Operator overloading is one of the important features of object-oriented programming in Python. This feature allows us to use the same operator for more than one task. C++ supports operator overloading, but Java does not.

The process of changing the default behavior of an operator depending on the operands being used is called operator overloading in Python.

In simple words, the technique of giving special meanings to an operator is called operator overloading. The functionality of operators in Python depends on the built-in classes. However, the same operator will behave differently for objects of different classes.

For example, we use “+” operator for adding two numbers. In Python, we can also use this operator for concatenating two strings as well as adding member variables of two different classes. This is because the built-in ‘+’ operator is applied by int class as well as str class.

Similarly, when we use “*”  multiplication operator on numbers, it multiplies them, but when we use on a string and an integer, it repeats the string.

The following example code illustrates how “+” operator can be overloaded.

x = 1
y = 2
print(x + y) # Adds two numbers.
print(x * y) # Multiplying the two numbers.

x = "Python"
y = " Language"
print(x + y) # Concatenates two strings.
print(x + y * 2) # Concatenates and repeats string.
Output:
       3
       2
       Python Language
       Python Language Language

In this code, x and y are initially assigned values 1 and 2, which are both integers. When we have used the + operator, it performs addition, resulting in the sum of 1 and 2, which is 3. Similarly, the * operator multiplies 1 and 2, resulting in 2.

After that, x and y are assigned strings, “Python” and ” Language,” respectively. When we have used the + operator with strings, it concatenates them, so x + y combines the two strings to create “Python Language.”

The last statement demonstrates operator overloading in the case of string multiplication. When we have used the multiplication operator (*) with a string and an integer, it repeats the string the specified number of times. So, x + y * 2 concatenates “Python” with ” Language” repeated twice, resulting in “Python Language Language.”

The above code demonstrates operator overloading in Python. It shows how the same operator, such as + and *, can perform different operations based on the data types involved.

How to Overload Operators in Python?


Python provides some special functions or methods to implement operator overloading. These methods are called magic methods that have double underscores (__) at the beginning and end of their names. They are used to overload operators with the object type of operands.


The magic methods are automatically called by Python when they are associated with their particular operators. For example, the magic method associated with “+” operator is __add__() method. Python will automatically call __add__() method to perform the overloaded addition operation.

Example 1:

# Define a class named Test.
class Test:
    def __init__(self, x):
        self.x = x
  # Overload the plus operator to add an integer value of two objects.
    def __add__(self, other):
        return self.x + other.x

# Outside the class definition.
# Create instances of class Test by passing integer values.
t1 = Test(20)
t2 = Test(30)

# Overloading + operator call by extending the '__add__' method.
result = t1 + t2
print(result)
Output:
       50

In this example program, we have defined a class named Test that contains one member variable x. This variable is initialized by using __init__() constructor method. Within the class, we have used the built-in method __add__() for overloading the plus “+” operator.

This method specifically adds two objects, which signifies the concept of operator overloading. It takes two arguments: self (representing the instance of the current class) and other (representing the other object we want to add).

After that, we have created two instances t1 and t2 of class Test with initializing values of data member. Then, we have performed the addition of two objects t1 + t2, assigned the outcome into a variable named result and printed it on the consol.

When Python executes the statement t1 + t2, it expands as t1.__add__(t2), meaning that t1 object invokes the built-in addition overloading method __add__() with t2 as an argument. After invocation of this method, the control goes to the definition part of __add__() method where; it contains two arguments self and other.

The self object in the argument represents the current object t1, which invokes the method t1.__add__(t2). The other object in the argument represents t2 object which is passed as an argument. After that, the addition operation is performed by accessing the class data member as self.x + other.x. After computation, the result is assigned to a variable named result and displayed it.

Thus, to implement operator overloading in Python, you will have to need to define the appropriate magic method according to the operator in the class definition.

Magic Methods for Different Operators and Functions


The following tables show the operators that can be overloaded along with their corresponding magic methods:


1. List of binary operators and their corresponding magic method:

OperatorMagic MethodDescription
+__add__(self, other)Invoked for addition operations
__sub__(self, other)Invoked for subtraction operations
*__mul__(self, other)Invoked for multiplication operations
/__truediv__(self, other)Invoked for division operations
//__floordiv__(self, other)Invoked for floor division operations
%__mod__(self, other)Invoked for modulus operations
**__pow__(self, other)Invoked for power operations
<<__lshift__(self, other)Invoked for left-shift operations
>>__rshift__(self, other)Invoked for right-shift operations
&__and__(self, other)Invoked for binary AND operations
^__xor__(self, other)Invoked for binary exclusive OR operations
|__or__(self, other)Invoked for binary OR operations

2. List of unary operators and their corresponding magic method:

OperatorMagic MethodDescription
__neg__(self)Invoked for unary negation operator
+__pos__(self)Invoked for unary plus operator
abs()__abs__(self)Invoked for built-in abs() function. It returns absolute value.
~__invert__(self)Invoked for unary invert operator

3. List of built-in functions and their corresponding magic method for conversion operations:

FunctionsMagic MethodDescription
complex()__complex__(self)Invoked for complex() function
int()__int__(self)Invoked for int() function
long()__long__(self)Invoked for long() function
float()__float__(self)Invoked for float() function
oct()__oct__()Invoked for oct() function
hex()__hex__()Invoked for hex() function

4. List of comparison operators and their corresponding magic method:

OperatorMagic MethodDescription
<__lt__(self, other)Invoked for less than operations
<=__le__(self, other)Invoked for less than or equal to operations
>__gt__(self, other)Invoked for greater than operations
>=__ge__(self, other)Invoked for greater than or equal to operations
==__eq__(self, other)Invoked for equality operations
!=__ne__(self, other)Invoked for inequality operations

5. List of assignment operators and their corresponding magic method:

OperatorMagic MethodDescription
+=__iadd__(self, other)Invoked for addition assignment operations
-=__isub__(self, other)Invoked for subtraction assignment operations
*=__imul__(self, other)Invoked for multiplication assignment operations
/=__idiv__(self, other)Invoked for division assignment operations
//=__ifloordiv__(self, other)Invoked for floor division assignment operations
%=__imod__(self, other)Invoked for modulus assignment operations
**=__ipow__(self, other)Invoked for power assignment operations
<<=__ilshift__(self, other)Invoked for left-shift assignment operations
>>=__irshift__(self, other)Invoked for right-shift assignment operations
&=__iand__(self, other)Invoked for binary AND assignment operations
^=__ixor__(self, other)Invoked for binary exclusive-OR assignment operations
|=__ior__(self, other)Invoked for binary OR assignment operations

Operator Overloading Example Programs


Let’s take some important example programs based on the above operators and their corresponding magic methods that you should must practice.

Overloading Binary Operator Examples

Example 1: 

# Python program to overload the plus operator.
class Employee:
    # Overload the + operator to add the salary of two instances.
    def __add__(self, other):
        return self.salary + other.salary

# Create two instances of class Employee.
emp1 = Employee()
emp2 = Employee()

# Initialize the variable with values.
emp1.salary = 40000
emp2.salary = 30000

# Invoke the overloaded + operator and print the result.
print(emp1 + emp2)
Output:
       70000

Example 2:

# Python program to overload the plus operator for two integer numbers and string values.
class Test:
    def __init__(self, x):
        self.x = x

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

t1 = Test(20)
t2 = Test(30)
print(t1 + t2)

t1 = Test("Python")
t2 = Test(" Programming")
print(t1 + t2)
Output:
       50
       Python Programming

Let’s take an example in which we will create a class named Complex and implement __add__() method to add two complex numbers. We will display the result by overloading the + operator.

Example 3:

class Complex:
    def __init__(self, real, imag):
        self.real = real
        self.imag = imag

    def __add__(self, other):
        real = self.real + other.real
        imag = self.real + other.real
        return(complex(real, imag))

    def display(self):
        print(self.real, "+ i",self.imag)

c1 = Complex(2, 10)
c2 = Complex(3, 9)
c1.display()
c2.display()

c3 = c1 + c2
print(c3)
Output:
       2 + i 10
       3 + i 9
       (5+5j)

Alike, the plus overloading operator, we can also overload the subtraction (-) operator. Let’s take an example based on it.

Example 4:

# Python program to overload the minus operator.
class MyClass:
    def __init__(self, value):
        self.value = value

    def __sub__(self, other):
        return self.value - other.value

# Create instances of class MyClass with integer values
obj1 = MyClass(50)
obj2 = MyClass(20)

# Invoke the overloaded "-" operator
result = obj1 - obj2

# Access the result
print(result)
Output:
       30

In this example, we have defined a class named MyClass, which has a constructor method __init__() to initialize objects with a value. Then, we have overloaded the – operator by defining the __sub__() method within the class. After that, we have created two instances of MyClass, obj1 and obj2, each initialized with integer values.

We have invoked the overloaded – operator with these instances, i.e., obj1 – obj2. Python automatically calls the __sub__ method defined in the class to perform the subtraction operation. The result is stored in the result variable, which holds the difference between the value attributes of obj1 and obj2. In this case, the result is 50 – 20, which equals 30.

Example 5:

# Python program to overload the power operator.
class Test:
    def __init__(self, x):
        self.x = x

    def __pow__(self, other):
        return self.x ** other.x

t1 = Test(2)
t2 = Test(10)
print(t1 ** t2)
Output:
       1024

Overloading Comparison > Operator Example

Let’s some example program based on the overloading of comparison operators.

Example 6:

# Python program to overload the comparison > operator.
class Test:
    def __init__(self, x):
        self.x = x

    def __gt__(self, other):
        if(self.x > other.x):
            return True
        else:
            return False

t1 = Test(20)
t2 = Test(10)
if(t1 > t2):
    print("t1 is greater than t2")
else:
    print("t2 is greater than t1")
Output:
       t1 is greater than t2

Example 7:

# Python program to overload the equality and less than comparison operators.
class Test:
    def __init__(self, x):
        self.x = x

    def __lt__(self, other):
        if(self.x < other.x):
            return "t1 is less than t2"
        else:
            return "t2 is less than t1"

    def __eq__(self, other):
        if(self.x == other.x):
            return "Both are equal"
        else:
            return "Not equal"

t1 = Test(20)
t2 = Test(10)
print(t1 < t2)

t3 = Test(40)
t4 = Test(40)
print(t3 == t4)
Output:
        t2 is less than t1
        Both are equal

Overloading Assignment Operators Example

Let’s take an example program based on the overloading of assignment += operator.

Example 8:

# Python program to overload the assignment operator.
class Number:
    def __init__(self, value):
        self.value = value

    def __iadd__(self, other):
        # Overload the assignment operator +=.
        self.value += other
        return self

# Create instances of the class Number.
num1 = Number(5)

# Use the overloaded "+=" operator
num1 += 3

# Access and print the result.
print(num1.value) 
Output:
        8

In this simple example, we have defined a class called Number with an __init__ method to initialize the object with a numerical value. Then, we have overloaded the += operator by defining the __iadd__ method within the class.

This method adds the value on the right of += to the value attribute of the instance and returns the modified object. After that, we have created an instance of the Number class by passing the argument value 5 to its constructor method.

We have invoked the overloaded += operator with num1. When Python executes the statement num1 += 3, it automatically calls the __iadd__ method, adding 3 to the value attribute. The result is stored in a variable num1. You can see that num1.value now contains the updated value, which is 8.

Overloading Bitwise & Operator Example

Let’s take an example program in which we will overload bitwise & operator.

Example 9:

# Python program to overload the bitwise & operator.
class Number:
    def __init__(self, num):
        self.num = num

    def __and__(self, other):
        num = self.num & other.num
        return num

n1 = Number(14)
n2 = Number(28)
n3 = n1 & n2
print(n3)
Output:
        12

In this example code, we have defined a class Number that contains a constructor __init__() to initialize objects with a numerical value. Then, we have defined __and__() method to overload bitwise and (&) operator. This method performs a bitwise and operation between the num attribute of self and other and returns the result as an integer.

After that, we have created two objects of Number class by passing argument values 14 and 28, respectively to its constructor. Then, we have invoked overloaded bitwise and operator on objects n1 & n2 and stored the returned result into an variable n3. The invokation n1 & n2 expands as n1.__and__(n2).

In the definition part of this method, n1 represents the calling object that is self and n2 represents other object as an argument. The calculation is perfomed by using the dot (.) operator with these two objects self and other and the bitwise & operator. The result is stored into the object n3 and displayed it on the console.

Overloading Indexing [ ] Operator in Python


Python also provides the facility to overload the indexing operator ([ ]). This operator is useful in various contexts, such as getting the value at an index in sequences, obtaining the part of a sequence through slicing, or getting the value associated with a key in dictionaries. We can change its behavior using the __getitem__() magic method. Let’s take an example on it.

Example 10:

# Python program to overload the indexing operator.
class Order:
    def __init__(self, cart, course):
        self.cart = list(cart)
        self.course = course

    def __getitem__(self, item):
        return self.cart[item]

# Create an instance of the Order class
order = Order(["Science", "Engineering", "Medical"], "Different Courses")

# Access an item from the cart using square brackets
item = order[0]

# Print the result
print(item)
Output:
       Science

In this code, we have defined a class named Order that contains a constructor to initialize data attributes such as a list of items (cart) and course. Then, we have defined __getitem__() method within the class. This method allows us to access items in the cart using square brackets by returning the corresponding item from the list.

After that, we have created an instance of the Order class by passing argument values to its constructor. To access an item from the cart, we have used square brackets. In this case, we have accessed the item at index 0, which is “Science.” Finally, we have printed the value of item, which is the item at index 0.

Benefits of Operator Overloading


The benefits of operator overloading include:

  • Operator overloading simplifies code, making it more elegant and intuitive.
  • Code becomes more human-friendly and easier to understand.
  • We can use overloaded operators across projects.
  • Overloading operator can lead to more efficient and optimized code.
  • It maintains consistency when working with custom objects.

Real-World Examples of Using Operator Overloading


Although operator overloading is not just a theoretical concept in Python, but also it’s widely used in various Python libraries and frameworks. Some real-world examples include:

  • NumPy: It is a popular library for numerical computations, heavily relies on operator overloading to work with arrays.
  • Pandas: It is a data manipulation library, uses operator overloading for DataFrame operations.
  • SymPy: It is a symbolic mathematics library, employs operator overloading for symbolic expression manipulation.

In this tutorial, we have discussed operator overloading in Python with the help of various example programs. Operator overloading is not a unique concept to Python, but it is found in various programming languages, but its implementation may differ.

We cannot overload all Python operators. Some operators have fixed behavior in Python and cannot be customized. Hope that you will have understood the basic concepts of operator overloading and practiced all programs. In the next, we will get the complete knowledge of method overriding in Python with the help of various advanced example programs.
Thanks for reading!!!

⇐ PrevNext ⇒

Please share your love