Operator Overloading is a handy feature in Python that allows us to “overload” or “over-ride” an operator with our own custom code. Operators such as +
, -
, *
, /
may not work in certain situations, such as when adding together two objects from custom classes you may have created.
In order to resolve this, we “overload” these operators to ensure it correctly adds the objects in a way that we find acceptable.
Regular Data Types
You must have already used various operators with the regular data types like int and string, like the example below.
print(3 + 5)
print("Hello" + "World")
print(5.3 + 1.2)
These Data types have defined behavior for these various operations. The Custom Classes that we make however, do not have defined behavior (by default). We need to code in the behavior for each operator into the Classes that we make, in order for it work correctly.
In the below example, we will demonstrate what happens if you try to use the + operator on two objects of Class Data.
class Data:
def __init__(self, n):
self.value = n
d1 = Data(5)
d2 = Data(2)
print(d1 + d2)
The above code produces the following error:
TypeError: unsupported operand type(s) for +: 'Data' and 'Data'
This error was thrown since there is no support for the addition between two Data objects.
Operator Overloading
The operators that we use so often, +, *, -, / and others have special methods associated with them that we need to write. The + operator for instance, has the __add__()
function which gets called when the + operator is used. You can envision the function call as object1.__add__(object2)
.
The following snipped overloads the __add__()
function allowing for the addition of two data objects.
class Data:
def __init__(self, n):
self.value = n
def __add__(self, obj):
return Data(self.value + obj.value)
d1 = Data(5)
d2 = Data(2)
d3 = d1 + d2
The +
operator now works, because there is an appropriate __add__()
method, which doesn’t try adding the objects, rather it adds the variables inside the object. You can add more than just one variable too. If your object has several, you can add them all together in the overloaded method.
Also note, that the reason we return a Data object from __add__()
was because we were assigning it to a Data object. Otherwise d3 would have ended up as an int
, not a Data object.
To output the new value in d3
, we can always do print(d3.value)
, but what if we just overloaded the print operator itself? That way we could just do print(d3)
, and we could print out the value(s) we want to display.
In order to overload print()
, we need to overload the __str__()
method in our Data class.
class Data:
def __init__(self, n):
self.value = n
def __add__(self, obj):
return Data(self.value + obj.value)
def __str__(self):
return str(self.value)
d1 = Data(5)
d2 = Data(2)
d3 = d1 + d2
print(d3)
The __str__()
must return a string, hence we have to convert self.value
to string before returning. In the case of any other data type, an error will be thrown.
Output:
7
In this manner, you can overload almost any operator in Python. We have a complete list of overloadable operators in the tables below.
List of Overloadable Operators in Python
Besides the below operators, there are a few other functions and built-in methods that you can overload, such as __len__()
.
Operator | Function |
---|---|
+ | __add__(self, other) |
- | __sub__(self, other) |
* | __mul__(self, other) |
/ | __truediv__(self, other) |
% | __mod__(self, other) |
// | __floordiv__(self, other) |
** | __pow__(self, other) |
< | __lt__(self, other) |
<= | __le__(self, other) |
== | __eq__(self, other) |
!= | __ne__(self, other) |
> | __gt__(self, other) |
>= | __ge__(self, other) |
Assignment based operators: (Note that the assignment operator itself, =
, is not overloadable.
Operator | Function |
---|---|
-= | __ISUB__(SELF, OTHER) |
+= | __IADD__(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) |
This marks the end of the Python Operator Overloading Tutorial. Any suggestions or contributions for CodersLegacy are more than welcome. Questions regarding the tutorial content can be asked in the comments section below.