Course Progress60%
🍎 Python OOP Topic 60 / 100
⏳ 8 min read

Dunder Methods

__str__, __len__, __add__ — special methods that make your objects behave like Python built-ins.

"Dunder methods are Python's protocol for making custom objects feel native. When your class has __str__, print() works. When it has __len__, len() works. Objects become first-class citizens."

— ShurAI

What are Dunder Methods?

Dunder (double-underscore) methods are special methods with names like __str__, __len__, __add__. Python calls them automatically when you use built-in functions or operators on your objects. They let your custom classes behave like built-in types:

You write Python calls Dunder method
print(obj)Needs a string representation__str__
repr(obj)Needs a debug representation__repr__
len(obj)Needs a length__len__
a + bAdd two objects__add__
a == bCompare equality__eq__
a < bCompare less-than__lt__

__str__ and __repr__

python
class Book:
    def __init__(self, title, author):
        self.title  = title
        self.author = author

    def __str__(self):
        return f'"{self.title}" by {self.author}'

    def __repr__(self):
        return f'Book("{self.title}", "{self.author}")'

b = Book("Python 101", "Riya")
print(b)         # "Python 101" by Riya  — calls __str__
print(repr(b))   # Book("Python 101", "Riya")  — calls __repr__
__str__ vs __repr__

__str__ is for human-readable display (used by print()). __repr__ is for developers — ideally a string that could recreate the object. When only __repr__ is defined, print() uses it as a fallback.

__len__ and __add__

python
class Playlist:
    def __init__(self, name, songs):
        self.name  = name
        self.songs = songs    # list of song names

    def __len__(self):
        return len(self.songs)

    def __str__(self):
        return f"Playlist '{self.name}' ({len(self)} songs)"

    def __add__(self, other):    # enables playlist1 + playlist2
        return Playlist(
            f"{self.name} + {other.name}",
            self.songs + other.songs
        )

p1 = Playlist("Chill",  ["Song A", "Song B"])
p2 = Playlist("Party", ["Song C", "Song D", "Song E"])
p3 = p1 + p2

print(p1)          # Playlist 'Chill' (2 songs)
print(len(p2))     # 3
print(p3)          # Playlist 'Chill + Party' (5 songs)

__eq__ and __lt__

python
class Score:
    def __init__(self, player, points):
        self.player = player
        self.points = points

    def __eq__(self, other):
        return self.points == other.points

    def __lt__(self, other):
        return self.points < other.points

    def __str__(self):
        return f"{self.player}: {self.points}"

scores = [Score("Riya", 450), Score("Arjun", 380), Score("Sneha", 520)]
print(sorted(scores, reverse=True))   # sorted() uses __lt__
# [Sneha: 520, Riya: 450, Arjun: 380]

"The real magic of dunder methods is that your objects integrate with Python's ecosystem — sorted(), len(), print(), + operator. They stop being 'custom things' and become proper Python citizens."

— ShurAI

🧠 Quiz — Q1

What is a dunder method?

🧠 Quiz — Q2

You define __str__ on your class. When does Python call it?

🧠 Quiz — Q3

What should __len__ return?

🧠 Quiz — Q4

If your class has __add__(self, other), what Python syntax does it enable?