Operator overloading refers to the ability of a built-in operator to behave differently according to the different operands we use with it.

For example, the operator ‘+’ is used to:

- Add two integers.
- Concatenate two strings.
- Merge two lists.

```
#Concatenate two strings
print("Codes"+"Dope")
#Add two numbers
print(9+6)
#Multiply two numbers
print(6*5)
#Repeation of a string
print("Welcome"*3)
```

**Output:**

CodesDope

15

30

WelcomeWelcomeWelcome

*Here, the ‘+’ and ‘*’ operators have been overloaded for int and str classes.*

## Advantages of Operator Overloading:

- It provides reusability, instead of writing multiple methods that differ slightly we can simply write one method and overload it.
- It also improves code clarity and eliminates complexity.
- It makes code concise and simple to understand.

## Why operator overloading?

Consider two objects of a user-defined data type, now if we try to multiply both with an operator `*`

the compiler will throw an error because the compiler doesn’t know how to multiply the operands.

For example, let's take a case where we have defined our own *Coordinates* class with two attributes *x* and *y*. Now, objects of this class would represent different points and using `+`

directly on these points (objects) would give us an error. Let's look at the example to understand this.

```
class Coordinates:
def __init__(self, x, y):
self.x = x
self.y = y
p1 = Coordinates(1, 2)
p2 = Coordinates(2, 3)
print(p1+p2)
```

**Output:**

****Traceback (most recent call last):
File "<string>", line 9, in <module>

print(p1+p2)

TypeError: unsupported operand type(s) for +: 'Coordinates' and 'Coordinates'.

Here, the compiler is unable to understand what `p1+p2`

means.

To resolve this problem we can define a method to overload the `+`

operator to change its functionality as per our needs.

## How to perform operator overloading?

**begin and end with a double underscore (__)**.

`*`

operator, the magic method `__mul__`

is automatically invoked in which the operation for `*`

operator is already defined.`+`

' operator, we will use the `__add__`

magic method.```
class Coordinates:
def __init__(self, a,b):
self.a = a
self.b=b
# adding two objects
def __add__(self, o):
a=self.a+o.a
b=self.b+o.b
s3=Coordinates(a,b)
return s3
p1=Coordinates(30,40)
p2=Coordinates(70,80)
s3=p1+p2
print(s3.a) #sum of the x coordinates
print(s3.b) #sum of the y coordinates
```

**Output:**

****100

120

Here we have defined the `__add()__`

method and passed the Coordinates object and got the sum of the coordinates as the result.

This is how we can define the magic methods and can also *change their behavior according to our needs*.

In python whenever we use ‘+’ operator, python directly call the method that is associated to it i.e. __add()__ method.

Python arithmetic on two complex numbers :

```
class complex:
def __init__(self, real, imag):
self.real = real
self.imag = imag
def __add__(self, other):
return complex(self.real+other.real, self.imag+other.imag)
def __sub__(self, other):
return complex(self.real-other.real, self.imag-other.imag)
def __str__(self):
return str(round(self.real,2))+('+' if self.imag>=0 else '-')+str(round(abs(self.imag),2))+'i'
print("Enter real and imaginary part of complex No - 1(separeated by space)")
A = complex(*map(float,input().split())) #the numbers are split by the space between them and passed to the function. * is used to pass multiple values at the same time.
print("Enter real and imaginary part of complex No - 2(separeated by space)" )
B = complex(*map(float,input().split()))
print("Addition: " + str(A+B))
print("Subtraction: " + str(A-B))
```

**Output:**

Enter real and imaginary part of complex No - 1(separeated by space)

2 3

Enter real and imaginary part of complex No - 2(separeated by space)

4 5

Addition: 6.00+8.00i

Subtraction: -2.00-2.00i

Here, we have entered two complex numbers, containing their real and imaginary parts.

Now, these numbers are passed to the complex function, defined by us.

After writing (A+B) python will automatically call the `__add__()`

function because of (`+`

) symbol. The same will happen for (`-`

) symbol, the `__sub__()`

function will be called.

Our function will now add and subtract, both real and imaginary parts of the numbers together, simultaneously.

Now, the results will be passed to the `__str()__`

function, which will concatenate both the real and imaginary parts together.

### Python magic function for binary operators overloading** **

Operator | Description | Magic Method |
---|---|---|

+ | Addition | __add__(self, other) |

- | Subtraction | __sub__(self, other) |

* | Multiplication | __mul__(self, other) |

/ | Division | __truediv__(self, other) |

** | Power | __pow__(self, other) |

// | Floor Division | __floordiv__(self, other) |

% | Modulus | __mod__(self, other) |

<< | Bitwise Left Shift | __lshift__(self, other) |

>> | Bitwise Right Shift | __rshift__(self, other) |

& | Bitwise AND | __and__(self, other) |

| | Bitwise OR | __or__(self, other) |

^ | Bitwise XOR | __xor__(self, other) |

~ | Bitwise NOT | __invert__(self, other) |

Python magic function for comparison operators overloading

Python doesn't limit operator overloading to arithmetic operators. We can overload other operators like comparison, assignment operators as well.

For Example: If we want to overload greater than (`>`

) and equal to operator (`==`

)

```
class Comparison:
def __init__(self, a):
self.a = a
def __gt__(self, o):
if(self.a>o.a):
return "m1 is greater than m2"
else:
return "m2 is greater than m1"
def __eq__(self, o):
if(self.a == o.a):
return "Both are equal"
else:
return "Not equal"
m1 = Comparison(3)
m2 = Comparison(2)
print(m1>m2)
m3=Comparison(5)
m4=Comparison(6)
print(m3==m4)
```

**Output:**

m1 is greater than m2

Not equal

Here we are passing two numbers into the function.

Case 1- After writing `m1>m2`

, python will automatically call the `__gt__()`

function, because of the (`>`

) symbol

Case 2- Similarly, `__eq__()`

will be called automatically after writing `m3==m4`

.

Once the conditions are checked, we will get our result.

Table of the magic methods for comparison operators:

Operator | Description | Magic Method |
---|---|---|

< | Less Than | __lt__(SELF, OTHER) |

> | Greater Than | __gt__(SELF, OTHER) |

<= | Less Than Equals | __le__(SELF, OTHER) |

>= | Greater Than Equals | __ge__(SELF, OTHER) |

== | Equals | __eq__(SELF, OTHER) |

!= | Not Equals | __ne__(SELF, OTHER) |

Python magic function for assignment operators overloading

Assignment operators perform a particular operation on the value of a variable and assign the result to that variable.** **

Operator | Description | Magic Method |
---|---|---|

-= | Subtraction Assignment | __isub__(SELF, OTHER) |

+= | Addition Assignment | __iadd__(SELF, OTHER) |

*= | Multiplication Assignment | __imul__(SELF, OTHER) |

/= | Division Assignment | __idiv__(SELF, OTHER) |

**= | Power Assignment | __ipow__(SELF, OTHER) |

//= | Floor Division Assignment | __ifloordiv__(SELF, OTHER) |

%= | Modulus Assignment | __imod__(SELF, OTHER) |

>>= | Right Shift Assignment | __irshift__(SELF, OTHER) |

<<= | Left Shift Assignment | __ilshift__(SELF, OTHER) |

&= | AND Assignment | __iand__(SELF, OTHER) |

|= | OR Assignment | __ior__(SELF, OTHER) |

^= | XOR Assignment | __ixor__(SELF, OTHER) |

Now move ahead to the next chapter.

Learn the Python Programming Language and strengthen your grip on the subject.