Home/Learn/Python A–Z/Dunder Methods — __str__, __eq__, __len__ & Operator Overloading

Dunder Methods — __str__, __eq__, __len__ & Operator Overloading

Intermediate
OOP

Double-underscore methods let your objects speak Python: print() calls __str__, == calls __eq__, len() calls __len__, and + calls __add__ — protocols, not magic.

Overview

Every Python operator and built-in function is a protocol: syntax on the outside, a dunder ("double underscore") method call underneath. print(obj) → __str__, obj == other → __eq__, len(obj) → __len__, obj[i] → __getitem__, for x in obj → __iter__. Implement the right dunders and your class works with the entire language — sorting, printing, containers, loops. This is Python's answer to Java's toString/equals/hashCode/Comparable, unified into one consistent system.

repr, str & Equality

__repr__ targets developers (debugger, lists); __str__ targets users (print). Define at least __repr__. Implementing __eq__ makes == compare by value — but sets __hash__ to None unless you define it too (equal objects must hash equal).

The value-object quartet: repr, str, eq, hash
class Money:
    def __init__(self, amount, currency="INR"):
        self.amount = amount
        self.currency = currency

    def __repr__(self):
        return f"Money({self.amount!r}, {self.currency!r})"

    def __str__(self):
        return f"₹{self.amount:,}" if self.currency == "INR" else f"{self.amount} {self.currency}"

    def __eq__(self, other):
        if not isinstance(other, Money):
            return NotImplemented
        return (self.amount, self.currency) == (other.amount, other.currency)

    def __hash__(self):
        return hash((self.amount, self.currency))

    def __add__(self, other):
        if self.currency != other.currency:
            raise ValueError("currency mismatch")
        return Money(self.amount + other.amount, self.currency)

a, b = Money(500), Money(500)
print(a)              # ₹500 (str)
print([a])            # [Money(500, 'INR')] — lists use repr!
print(a == b)         # True — value equality
print(a + Money(250)) # ₹750 — our __add__
print(len({a, b}))    # 1 — hashing consistent with equality

Container & Comparison Protocols

Implement __len__/__getitem__/__contains__ and your object behaves like a collection. __lt__ makes objects sortable without a key function.

Act like a list; sort like a number
class Playlist:
    def __init__(self, *songs):
        self._songs = list(songs)

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

    def __getitem__(self, index):        # enables [] AND iteration!
        return self._songs[index]

    def __contains__(self, song):
        return song in self._songs

pl = Playlist("Kesariya", "Tum Hi Ho", "Agar Tum Saath Ho")
print(len(pl))               # 3
print(pl[0])                 # Kesariya
print("Tum Hi Ho" in pl)     # True
for s in pl:                 # __getitem__ powers the loop
    print("-", s)

class Version:
    def __init__(self, major, minor):
        self.t = (major, minor)
    def __lt__(self, other):             # sortable
        return self.t < other.t
    def __repr__(self):
        return f"v{self.t[0]}.{self.t[1]}"

print(sorted([Version(2, 1), Version(1, 9)]))   # [v1.9, v2.1]

Key Points to Remember

  • 1__repr__ for developers (always define it); __str__ for users; containers show repr
  • 2Defining __eq__ without __hash__ makes objects unhashable — define both, consistently
  • 3__len__ + __getitem__ + __contains__ = your object works with len(), [], in, and for-loops
  • 4Return NotImplemented (not raise) from comparison dunders for foreign types

Interview Questions

Sign in to ask Aria
1

__str__ vs __repr__ — when is each called, and which should you always define?

MediumFlipkart
2

You defined __eq__ and your objects stopped working in a set. Why?

HardMicrosoft
3

How does the in operator decide membership for a custom class?

MediumUber

Ask Aria about Dunder Methods — __str__, __eq__, __len__ & Operator Overloading

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…