Special Dunder Methods
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.
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.
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.
# 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:
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:
def get_string_format(self):
return f'Point({self.x})' # Custom naming is not integration-friendly
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.