Keeping you updated with latest technology trends, Join DataFlair on Telegram

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.

In Python, an operator lets us perform an operation/procedure on one or more operands(values). Read up on our article on Python Operators. But for now, let’s take an example.

`>>> 42+1`

43
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. Let’s discuss Python Syntax before proceeding.

`>>> '42'+'1'`

‘421’

`>>> '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):
self.whole=whole
self.fraction=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+obj2

TypeError: 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.

## 3. 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-

### a. Python Binary Operators

__sub__ for –

__mul__ for *

__truediv__ for /

__floordiv__ for //

__mod__ for %

__pow__ for **

__and__ for &

__xor__ for ^

__or__ for |

__lshift__ for <<

__rshift__ for >>

In our article on Python Methods, we discussed these.

### b. Python Extended Assignments

__isub__ for -=

__imul__ for *=

__idiv__ for /=

__ifloordiv__ for //=

__imod__ for %=

__ipow__ for **=

__ilshift__ for <<=

__irshift__ for >>=

__iand__ for &=

__ixor__ for ^=

__ior__ for |=

### c. 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()

### d. Python Comparison Operators

__lt__ for <

__le__ for <=

__eq__ for ==

__ne__ for !=

__ge__ for >=

__gt__ for >

Read up on what we have to say about Python Variables and Python Numbers.

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

3

`>>> 2+a`

3

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):
self.whole=whole
self.fraction=fraction
def shownumber(self):
print(f"I am {self.whole}.{self.fraction}")
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).

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):
self.x=x
def __pow__(self,other):
return self.x**other.x
>>> a=itspower(2)
>>> b=itspower(10)
>>> a**b```

1024
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):
self.name=name
self.age=age
def __gt__(self,other):
if self.age>other.age:
return True
return False
def __abs__(self):
return abs(self.age)
return self.age+other.age
>>> Nick=Person('Nick',7)
>>> Angela=Person('Angela',5)
>>> Nick>Angela```

True

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

8

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

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

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

’11’

`>>> 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.

## 6. Conclusion

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. Furthermore, if you have any doubt/query, feel free to ask in the comment section.
– Python Features
– Python Functions and Arguments
For reference

### 5 Responses

1. srinivas says:

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

-ob1
print(ob1)
but not getting it could you help me to resolve this.

• DataFlair Team says:

Hello Srinivas,

class A:
def __init__(self,x):
self.x=x
def __neg__(self):
return -self.x
Now, create an object of this class:
ob1=A(7)
And now, perform negation on it:
print(-ob1)
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: