This is an introduction to dunder methods in Python, to help you understand what they are and what they are for.
(If you are new here and have no idea what a Pydon't is, you may want to read the Pydon't Manifesto.)
Introduction
Python is a language that has a rich set of built-in functions and operators that work really well with the built-in types.
For example, the operator +
works on numbers, as addition, but it also works on strings, lists, and tuples, as concatenation:
>>> 1 + 2.3
3.3
>>> [1, 2, 3] + [4, 5, 6]
[1, 2, 3, 4, 5, 6]
But what is it that defines that +
is addition for numbers (integers and floats)
and concatenation for lists, tuples, strings?
What if I wanted +
to work on other types?
Can I do that?
The short answer is “yes”, and that happens through dunder methods, the object of study in this Pydon't. In this Pydon't, you will
- understand what are dunder methods;
- why they are called like that;
- see various useful dunder methods;
- learn about what dunder methods correspond to what built-ins;
- write your own dunder methods for example classes; and
- realise that dunder methods are like any other method you have written before.
You can now get your free copy of the ebook “Pydon'ts – Write beautiful Python code” on Gumroad to help support the series of “Pydon't” articles 💪.
What are dunder methods?
In Python, dunder methods are methods that allow instances of a class to interact with the built-in functions and operators of the language.
The word “dunder” comes from “double underscore”, because the names of dunder methods start and end with two underscores,
for example __str__
or __add__
.
Typically, dunder methods are not invoked directly by the programmer, making it look like they are called by magic.
That is why dunder methods are also referred to as “magic methods” sometimes.1
Dunder methods are not called magically, though. They are just called implicitly by the language, at specific times that are well-defined, and that depend on the dunder method in question.
The dunder method everyone knows
If you have defined classes in Python, you are bound to have crossed paths with a dunder method: __init__
.
The dunder method __init__
is responsible for initialising your instance of the class,
which is why it is in there that you usually set a bunch of attributes related to arguments the class received.
For example, if you were creating an instance of a class Square
,
you would create the attribute for the side length in __init__
:
class Square:
def __init__(self, side_length):
"""__init__ is the dunder method that INITialises the instance.
To create a square, we need to know the length of its side,
so that will be passed as an argument later, e.g. with Square(1).
To make sure the instance knows its own side length,
we save it with self.side_length = side_length.
"""
print("Inside init!")
self.side_length =...