Customising Operators in Python
24 Apr 2016Python classes allow the encapsulation of functionality in cleanly defined objects, and when used well can allow abstractions in usage that make for more understandable and readable code.
Consider the simple example of a class that defines a 3-vector, which I will
call Vector3
. It takes an x, y and z value and implements simple addition of
other vectors:
In code which manipulates vectors, we no longer need to manually write out the addition operations for each of the coordinates, but can simply add two vectors like:
Defining Operators
The add
method above is a nice abstraction, however it is limited by the fact
that we need to know to remember the interface, and that the use of a method
call with the second object as an argument is a little clunky. A nice solution
is to make our class support the +
addition operator, so that the last line
of the above code snippet becomes simply:
Python achieves this through the use of special methods, identifiable by
starting and ending with two underscores. You may have seen other special
methods like __init__
above, however some of these methods define the
behaviour when an operator is applied.
By default, trying to add two objects of a cusom class will result in a
TypeError
:
To support the addition operator, we need to define the
__add__
method with the signature:
Fortunately, this has the same signature as the add
method we defined above,
so simply renaming the method to __add__
will make additions of Vector3
objects work as intended.
Complete Implementation
Any of the Python operators can be overloaded in this way - see the documentation on the Python data model for a full listing, but the most commonly used are the numeric operators:
+
–__add__
-
–__sub__
*
–__mul__
/
–__truediv__
**
–__pow__
and the logical operators:
==
–__eq__
!=
–__ne__
<
–__lt__
>
–__gt__
<=
–__le__
>=
–__ge__
and
–__and__
or
–__or__
There are also the augmented assignment operators, that modify a variable
in-place, usually used for scaling or incrementing numeric values. These are
named with a leading ‘i’, like __iadd__
for the +=
operator.
Below is a more complete version of the Vector3
class from above,
demonstrating the implementation and usage of the normal and in-place additon
and subtraction operators. A __str__
special method has also been added to
provide decriptive printing of Vector3
objects when passed to the print
function.