intermediate

Special Dunder Methods

7 min readLast updated: 2026-07-12

Overview

Dunder (double underscore) methods let you customize how your objects behave with built-in Python operators and functions.

Learning Objectives

  • Implement str and repr to format printed objects.
  • Overload comparison and arithmetic operators.
  • Enable len() calls on custom classes by implementing len.

Concept Explanation

Dunder methods (like __init__, __str__, __repr__, __len__, and __eq__) let custom classes integrate with standard Python functions. For example, implementing __len__ lets you call len() on instances, and implementing __eq__ lets you compare instances using ==.

Code Examples

Example 1 — Basics

This example introduces the fundamental syntax and concepts.

python
class Book:
    def __init__(self, title): self.title = title
    def __repr__(self): return f'Book({self.title})'

Example 2 — Everyday Usage

This example demonstrates a realistic scenario handling business parameters.

python
class Box:
    def __init__(self, size):
        self.size = size

    def __eq__(self, other):
        if not isinstance(other, Box): return False
        return self.size == other.size

    def __str__(self):
        return f'Box of size {self.size}'

b1 = Box(10)
b2 = Box(10)
print(b1 == b2) # True (uses __eq__)
print(b1) # 'Box of size 10' (uses __str__)

Example 3 — Advanced Example

This example shows clean, production-grade code structure following senior development standards.

python
# Custom collection wrapper exposing length and bracket index lookups
class TasksQueue:
    def __init__(self):
        self._tasks = []

    def add(self, t):
        self._tasks.append(t)

    def __len__(self):
        return len(self._tasks) # Exposes len() protocol

    def __getitem__(self, idx):
        return self._tasks[idx] # Exposes bracket lookup index syntax

q = TasksQueue()
q.add('Task A')
print(len(q))
print(q[0])

Visual Flow

The following execution flow represents the step-by-step evaluation inside the interpreter:

text
Call operation (e.g. len) → Check class definition for matching dunder (__len__) → Run method → Return value

Common Mistakes

Review these common pitfalls when working with this topic:

  • Confusing str (user-facing representation) with repr (developer debug representation).
  • Implementing comparison dunders without checking the class type of the other object.
  • Overloading operators in ways that are confusing or non-intuitive.
  • Expecting dunders to execute automatically without defining their protocols.

Best Practices

Enforce these Pythonic best practices in your codebase:

❌ Don't
python
def get_string_format(self):
    return f'Point({self.x})' # Custom naming is not integration-friendly
✅ Do
python
def __repr__(self):
    return f'Point({self.x})' # Automatically maps to print() and debug displays

Quick Revision

Use these key summaries for last-minute revision:

  • Dunder methods have double underscores at both ends.
  • They integrate custom classes with built-in operators.
  • str provides user-friendly text output.
  • repr provides developer-facing debug output.
  • eq overloads the == comparison operator.
  • getitem enables bracket index lookup queries.