Intro to “Dunder” Methods in Python

Michael Jester
3 min readOct 26, 2020


When learning Python, one thing I learned that was different in other languages are the double underscore (“dunder”, magic, or special) methods that can be used in classes. There are definitely ways to do this in other languages, but python makes the process a lot easier.

A class can implement certain operations that are invoked by special syntax (such as arithmetic operations or subscripting and slicing) by defining methods with special names. This is Python’s approach to operator overloading, allowing classes to define their own behavior with respect to language operators.

— Python’s documentation on what are ‘dunder’ methods

Below I have an example Pet class with the most-used dunder methods.

class Pet:  def __init__(self, name, species): = name
self.species = species
def __repr__(self):
return "Pet('{}', '{}')".format(, self.species)
def __str__(self):
return "My pet, {}, the {}".format(, self.species)
def __add__(self, other):
if isinstance(other, Pet):
return "{} and {}".format(,

return NotImplemented
def __del__(self):
return "{}, the {} is deleted".format(, self.species)
# Creating an instance
my_pet = Pet("Cookie Dough", "dog")
johns_pet = Pet("Henry", "cat")


This was is very similar to constructor in other languages. It is what happens when the class is initialized. So in the example, we are adding a name and a species.


This is usually used for debugging purposes, Python classifies this as “[a] built-in function to compute the “official” string representation of an object. […] This is typically used for debugging, so it is important that the representation is information-rich and unambiguous.”

So, when you call print(repr(my_pet)) it will return Pet(‘Cookie Dough', ‘dog').


The python docs consider this, “to compute the “informal” or nicely printable string representation of an object.” So while repr is for developer purposes, this is what is normally seen by the user of the application.

When you call print(str(my_pet)) it will return My pet, Cookie Dough, the dog.


This is what happens if someone tries to add two of the same classes together. The highest-level example I can provide is print(1 + 2). Maybe there is a reason why you would want something like this in your classes (hint: spoiler for later).

When you call print(my_pet + johns_pet) it will return Cookie Dough and Henry.


This mehtod is called when the instance is about to be destroyed. In the case above, when del my_pet is ran, then the system will print Cookie Dough, the dog is deleted.

A real life application

Taking a look inside the source code for the datetime module, there is a __add__ method for the timedelta class.

A picture of the code is listed below, but what it is doing firstly is checking if both sides are a timedelta format (if it is not then it will raise a NotImplemented error) and then added the two dates together.

How the datetime module adds two dates together

Additional resources:

Final notes…

Is there anything I missed? Any additional resources you want added to this page? Comment down below to help out!