Expert · Object-oriented programming · topic 38 of 50 · 30 min
Dunder (magic) methods
Explanation
What "dunder" means
"Dunder" is short for "double underscore". __init__ is read aloud as "dunder init". These special methods are also called magic methods, because you rarely call them yourself: Python calls them when you use an operator or a built-in function on your object.
| You write | Python calls |
|---|---|
| print(obj) or str(obj) | obj.__str__() |
| repr(obj), or obj shown inside a list | obj.__repr__() |
| a == b | a.__eq__(b) |
| a < b, and sorted(list_of_objects) | a.__lt__(b) |
| len(obj) | obj.__len__() |
| a + b | a.__add__(b) |
| x in obj | obj.__contains__(x) |
__str__ and __repr__
__str__ gives a friendly text for users, used by print(). __repr__ gives an exact text for programmers, used when debugging and when the object appears inside a list. A good __repr__ looks like the code that would create the object.
class Book:
def __init__(self, title, price):
self.title = title
self.price = price
def __str__(self):
return f"{self.title} (Rs {self.price})"
def __repr__(self):
return f"Book({self.title!r}, {self.price})"
b = Book("Wings of Fire", 299)
print(b) # Wings of Fire (Rs 299)
print([b]) # [Book('Wings of Fire', 299)]A Money class: __add__, __eq__ and __lt__
class Money:
def __init__(self, paise):
self.paise = paise # store whole paise: no float errors
def __add__(self, other):
if not isinstance(other, Money):
return NotImplemented
return Money(self.paise + other.paise) # a NEW object
def __eq__(self, other):
if not isinstance(other, Money):
return NotImplemented
return self.paise == other.paise
def __lt__(self, other):
return self.paise < other.paise
def __repr__(self):
return f"Money({self.paise})"
def __str__(self):
return f"Rs {self.paise // 100}.{self.paise % 100:02d}"
tea = Money(1500)
samosa = Money(2050)
print(tea + samosa) # Rs 35.50
print(Money(100) == Money(100)) # True
print(sorted([samosa, tea, Money(500)])) # smallest firstReturning NotImplemented (a special built-in value) tells Python "I do not know how to handle this type". Python then tries the other object, and if that fails too, it raises a clear TypeError. This is better than crashing with a confusing AttributeError.
__len__ and __contains__
class Playlist:
def __init__(self, name):
self.name = name
self.songs = []
def add(self, song):
self.songs.append(song)
def __len__(self):
return len(self.songs)
def __contains__(self, song):
return song in self.songs
p = Playlist("Road trip")
p.add("Kesariya")
p.add("Malang")
print(len(p)) # 2
print("Malang" in p) # True
print("Tum Hi Ho" in p) # FalseWatch the lesson
Dunder (magic) methods · 1/7
In this lesson you will learn dunder methods, the special methods that make your objects work with print, plus, equals and more.
Prefer a video by a teacher? Find free videos on “python magic methods dunder str repr eq add” on YouTube ↗
In real life: A shopping cart that adds up
An online kirana app adds up prices from many shops. Using a Money class with __add__ means cart totals are written as plain item1 + item2, money is stored in exact paise, and print() always shows a neat "Rs 35.50". Sorting items by price with sorted() works because of __lt__.
class Money:
def __init__(self, paise):
self.paise = paise
def __add__(self, other):
return Money(self.paise + other.paise)
def __str__(self):
return f"Rs {self.paise // 100}.{self.paise % 100:02d}"
cart = [Money(4500), Money(12000), Money(2999)]
total = Money(0)
for price in cart:
total = total + price
print("Cart total:", total)Practice (0/3 done)
Add a __str__ method to the Book class so that print(Book("Wings of Fire", 299)) shows exactly: Wings of Fire (Rs 299)
Complete the Money class (amounts in paise). Write __add__ so Money(1500) + Money(2050) gives a new Money(3550), and __eq__ so two Money objects with the same paise are equal.
Complete the Playlist class: write __len__ to return the number of songs, and __contains__ so that "Kesariya" in playlist works.
Quick quiz
Read more (free)
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.