Python Operator Overloading and Python Magic Methods

Master Python with 70+ Hands-on Projects and Get Job-ready - Learn Python

In this Python tutorial, we are going to discuss Python Operator Overloading, examples of operator overloading in python, and python magic methods with some operators: python binary operator, python comparison operator, python unary operators, and python extended assignments.

In the programming world, operator overloading is also called Operator Ad-hoc Polymorphism.

Indeed, it is a case of polymorphism where different operators have different implementations based on their arguments.

This is either defined by the programmer, by the programming language, or both.

So, let’s start the Python Magic Methods Tutorial.

Python Operator Overloading

Python Operator Overloading and Python Magic Methods

What is Python Operators Overloading?

In Python, an operator lets us perform an operation/procedure on one or more operands(values). Let’s take an example.

>>> 42+1



Here, we performed the addition of two numbers using the addition operator.

You know that we can apply this operator to Python string too. In that case, we call it the concatenation operator.

>>> '42'+'1'


>>> 'hello'+' '+'world'


‘hello world’

And then when we do this to Python list, we concatenate two lists.

>>> [1,2,3]+[4,5,6]


[1, 2, 3, 4, 5, 6]

Python does this implicitly, but what for when you want to apply this operator to your own class? Can we? Let’s give it a try.

In this python operator overloading tutorial, we take a class ‘myfloat’ to represent floating-point numbers.

>>> class myfloat:           
      def __init__(self,whole,fraction):        
      def shownumber(self):       
                print(f"I am {self.whole}.{self.fraction}")
>>> obj1=myfloat(3,7)
>>> obj1.shownumber()


I am 3.7
>>> obj2=myfloat(3,3)
>>> obj2.shownumber()


I am 3.3

Now, let’s try adding two objects.

>>> obj1+obj2


Traceback (most recent call last):

File “<pyshell#24>”, line 1, in <module> obj1+obj2TypeError: unsupported operand type(s) for +: ‘myfloat’ and ‘myfloat’

As you can see, this raised a TypeError. But don’t fret; we can do this, we’ll discuss in a later section.

Python Magic Methods

We observe that python methods have double underscores before and after their names. These are special methods and are also called ‘dunders’.

These help us implement functionality that a normal method can’t represent.

By now, we have come across only one magic method- __init__(). But we can, in fact, define our own magic methods to implement operator overloading in Python.

With this, we can define these operators to work on our custom classes. Some of these are-

1. Python Binary Operators

__add__ for +

__sub__ for –

__mul__ for *

__truediv__ for /

__floordiv__ for //

__mod__ for %

__pow__ for **

__and__ for &

__xor__ for ^

__or__ for |

__lshift__ for <<

__rshift__ for >>

2. Python Extended Assignments

__iadd__ for +=

__isub__ for -=

__imul__ for *=

__idiv__ for /=

__ifloordiv__ for //=

__imod__ for %=

__ipow__ for **=

__ilshift__ for <<=

__irshift__ for >>=

__iand__ for &=

__ixor__ for ^=

__ior__ for |=

3. Python Unary Operators

__neg__ for –

__pos__ for +

__abs__ for abs()

__invert__ for ~

__complex__ for complex()

__int__ for int()

__long__ for long()

__float__ for float()

__oct__ for oct()

__hex__ for hex()

4. Python Comparison Operators

__lt__ for <

__le__ for <=

__eq__ for ==

__ne__ for !=

__ge__ for >=

__gt__ for >

Others include __radd__ for reverse add.

>>> class myclass:
   def __init__(self,age):
   def __add__(self,other):
           return self.age+other
   def __radd__(self,other):
           return self.age+other
>>> a=myclass(1)
>>> a+2


>>> 2+a



If the interpreter cannot add left to right, it will call  __radd__() instead. Here, radd is in reverse/reflected add.

Python Operator Overloading Example

To be able to add our Python objects obj1 and obj2 for class ‘myfloat’, we can do the following.

>>> class myfloat:                
      def __init__(self,whole,fraction):  
      def shownumber(self):                       
           print(f"I am {self.whole}.{self.fraction}")   
      def __add__(self,other):      
           if (self.fraction+other.fraction)>9:                                        
                return myfloat(self.whole+other.whole+1,self.fraction+other.fraction-10)            return myfloat(self.whole+other.whole,self.fraction+other.fraction)

Here, we added another method __add__, that takes two parameters (‘self’ and ‘other’) for the two objects.

Then, it checks if the sum of the fraction parts of both objects is greater than 9. In that case, it transfers a 10 to the ‘whole’ part as a 1.

This is for the carry. It then returns an object with the sums of the whole and fraction parts of both objects.

However, if the condition isn’t met, it simply returns an object with the sums.

Let’s create objects obj1 and obj2 again, and try adding them.

>>> obj1=myfloat(3,7)
>>> obj1.shownumber()


I am 3.7
>>> obj2=myfloat(3,3)
>>> obj2.shownumber()


I am 3.3
>>> result=obj1+obj2
>>> print(f"I am {result.whole}.{result.fraction}")


I am 7.0

As you can see, it works absolutely fine now and lets us add two objects of class ‘myfloat’.

>>> result


<__main__.myfloat object at 0x0572FD10>

This is the resulting object of adding obj1 and obj2.

Here, the interpreter translates obj1+obj2 to obj1.__add__(obj2).

More Examples of Python Operator Overloading

To really understand something, once is never enough. So, let’s take another example of Operator overloading in Python.

>>> class itspower:                
        def __init__(self,x):                  
        def __pow__(self,other):                               
               return self.x**other.x             
>>> a=itspower(2)
>>> b=itspower(10)
>>> a**b



In this, we take a class ‘itspower’ and two methods __init__ and __pow__.

__pow__ takes two objects and returns the ‘x’ of first raised to the power of the ‘x’ of the second.

When we type a**b, the interpreter converts it implicitly to a.__pow__(b).

Now, let’s take another example to demonstrate few more such magic methods.

>>> class Person:
      def __init__(self,name,age):
      def __gt__(self,other):
         if self.age>other.age:
                return True
         return False
      def __abs__(self):
         return abs(self.age)
      def __iadd__(self,other):
         return self.age+other.age
>>> Nick=Person('Nick',7)
>>> Angela=Person('Angela',5)
>>> Nick>Angela


>>> Kim=Person('Kim',-8)
>>> abs(Kim)


>>> Tom=Person('Tom',7)
>>> Mikayla=Person('Mikayla',3)
>>> Tom+=Mikayla
>>> Tom



To leave this lesson on an engaging note, we would just like to leave this code here:

>>> '1'.__add__('1')


>>> 1.__add__(1)


SyntaxError: invalid syntax
>>> [1,2,3].__add__([4,5,6])


[1, 2, 3, 4, 5, 6]

So, this was all about Python Operator overloading and Python Magic Method Tutorial. Hope you like it.

Interview Questions on Python Operator Overloading and Python Magic Methods

  1. How do you overload an operator in Python?
  2. What are the magical methods in Python?
  3. Which operator is overloaded by invert in Python?
  4. How do you call a magic method in Python?
  5. Which operators cannot be overloaded?


Hence, we studied Python Operator overloading, in-effect, is pure syntactic sugar. Through it, we override a magic method to be able to use an operator on a custom class.

You give me 15 seconds I promise you best tutorials
Please share your happy experience on Google


6 Responses

  1. srinivas says:

    Hi,i oveloaded negation operator like this.
    def __neg__(self):
    return -self.x

    but not getting it could you help me to resolve this.

    • DataFlair Team says:

      Hello Srinivas,

      Let this be your class:
      class A:
      def __init__(self,x):
      def __neg__(self):
      return -self.x
      Now, create an object of this class:
      And now, perform negation on it:
      And you’ll have -7. It negated the value of x- we can rephrase this to say it negated the object ob1.
      Hope, this will solve your query. Keep visiting DataFlair

  2. lakshmi says:

    why 1.__add__(1) is getting error?

    • DataFlair Team says:

      For understanding this, you will have to go at a little depth.
      The python tokenizer tries to build the longest possible token. so the line is split into tokens as
      “1.”, “__add__”, “(“,”1″ ,”)”
      It parses the first token as “1.” which is a float value followed by an identifier. So, it throws syntax error.

      Note: (1).__add__(1) will return 2

  3. Abi says:

    Why class names are in lowercase? Earlier lessons mentioned that CAPS should be used for classes and exceptions?

  4. DataFlair says:

    Yes classes and exception names should start with Capital letter but in this article we are studying operator overloading which is a different than normal classes, hence the class names are in lowercase.

Leave a Reply

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