Python Operator Overloading

By

Learn how operator overloading works in Python: define dunder methods like __gt__ and __add__ so your classes work with comparison and arithmetic operators.

~~~

Operator overloading lets your classes work with Python operators like >, == or +. You define special methods on the class, the ones with double underscores around the name, and Python calls them when it finds the operator between two of your objects.

Let’s take a class Dog:

class Dog:
    # the Dog class
    def __init__(self, name, age):
        self.name = name
        self.age = age

Let’s create 2 Dog objects:

roger = Dog('Roger', 8)
syd = Dog('Syd', 7)

What happens if we try to compare them? Python has no idea how:

print(roger > syd)
# TypeError: '>' not supported between instances of 'Dog' and 'Dog'

That’s fair. Is Roger “greater” than Syd? By name? By age? We have to decide, and we tell Python by defining the __gt__() method (which means greater than).

Making objects comparable

We can use operator overloading to add a way to compare those 2 objects, based on the age property:

class Dog:
    # the Dog class
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def __gt__(self, other):
        return True if self.age > other.age else False

Now if you try running print(roger > syd) you will get the result True.

self is the object on the left of the operator, other is the one on the right. A nice detail: print(roger < syd) also works, even though we didn’t define __lt__(). Python swaps the operands and asks syd.__gt__(roger) instead.

In the same way we defined __gt__(), we can define the following methods:

Arithmetic operators

Then you have methods to interoperate with arithmetic operations:

For example we can decide that adding two dogs sums their ages:

def __add__(self, other):
    return self.age + other.age
print(roger + syd)
# 15

You get to choose what the operation returns. Here it’s a number, but it could just as well be a new Dog object.

There are a few more methods to work with other operators, but you got the idea.

One thing to watch out for

Be careful with __eq__(). As soon as you define it, your objects stop being hashable:

hash(roger)
# TypeError: unhashable type: 'Dog'

That means you can’t put them in a set or use them as dictionary keys anymore. If you need that, define a __hash__() method too, based on the same properties you use in __eq__().

Tagged: Python · All topics
~~~

Related posts about python: