If you’ve used the + or * operator on a str object in Python, you must have noticed its different behavior when compared to int or float objects:
>>> # Adds the two numbers
>>> 1 + 2
3
>>> # Concatenates the two strings
>>> 'Real' + 'Python'
'RealPython'
>>> # Gives the product
>>> 3 * 2
6
>>> # Repeats the string
>>> 'Python' * 3
'PythonPythonPython'
You might have wondered how the same built-in operator or function shows different behavior for objects of different classes. This is called operator overloading or function overloading respectively. This article will help you understand this mechanism, so that you can do the same in your own Python classes and make your objects more Pythonic.
You’ll learn the following:
- The API that handles operators and built-ins in Python
- The “secret” behind
len()and other built-ins - How to make your classes capable of using operators
- How to make your classes compatible with Python’s built-in functions
Free Bonus: Click here to get access to a free Python OOP Cheat Sheet that points you to the best tutorials, videos, and books to learn more about Object-Oriented Programming with Python.
As a bonus, you’ll also see an example class, objects of which will be compatible with many of these operators and functions. Let’s get started!
The Python Data Model
Say you have a class representing an online order having a cart (a list) and a customer (a str or instance of another class which represents a customer).
Note: If you need a refresher on OOP in Python, check out this tutorial on Real Python: Object-Oriented Programming (OOP) in Python
In such a case, it is quite natural to want to obtain the length of the cart list. Someone new to Python might decide to implement a method called get_cart_len() in their class to do this. But you can configure the built-in len() in such a way that it returns the length of the cart list when given our object.
In another case, we might want to append something to the cart. Again, someone new to Python would think of implementing a method called append_to_cart() that takes an item and appends it to the cart list. But you can configure the + operator in such a way that it appends a new item to the cart.
Python does all this using special methods. These special methods have a naming convention, where the name starts with two underscores, followed by an identifier and ends with another pair of underscores.
Essentially, each built-in function or operator has a special method corresponding to it. For example, there’s __len__(), corresponding to len(), and __add__(), corresponding to the + operator.
By default, most of the built-ins and operators will not work with objects of your classes. You must add the corresponding special methods in your class definition to make your object compatible with built-ins and operators.
When you do this, the behavior of the function or operator associated with it changes according to that defined in the method.
This is exactly what the Data Model (Section 3 of the Python documentation) helps you accomplish. It lists all the special methods available and provides you with the means of overloading built-in functions and operators so that you can use them on your own objects.
Let’s see what this means.
Fun fact: Due to the naming convention used for these methods, they are also called dunder methods which is a shorthand for double underscore methods. Sometimes they’re also referred to as special methods or magic methods. We prefer dunder methods though!