⨠Python Dunder Methods Guide¶
Beginner-friendly documentation about Python dunder methods (magic methods), special object behavior, and common object-oriented patterns.
đ Table of Contents¶
- đ What are Dunder Methods?
- đ init
- đ¨ī¸ str
- đ repr
- đ len
- âī¸ eq
- â add
- đĻ getitem
- đ iter
- đŽ Real 42 Examples
- â ī¸ Common Beginner Mistakes
- đ Best Practices
- đ Final Notes
đ What are Dunder Methods?¶
Dunder methods are: - special Python methods - surrounded by double underscores
Example:
__init__
The word:
dunder
means:
double underscore
Why Dunder Methods Exist¶
They allow Python objects to: - behave like built-in types - customize operators - customize printing - customize comparisons - support iteration
đ init¶
__init__ runs automatically when an object is created.
Used for: - initializing attributes - preparing object state
Example¶
class Player:
def __init__(self, name):
self.name = name
Creating the Object¶
player = Player("Sara")
đ¨ī¸ str¶
__str__ controls:
- readable object printing
Example¶
class Player:
def __init__(self, name):
self.name = name
def __str__(self):
return f"Player({self.name})"
Using str¶
player = Player("Sara")
print(player)
Output:
Player(Sara)
Why str is Useful¶
Without __str__, Python prints:
<object at 0x123456>
which is not very readable.
đ repr¶
__repr__ provides:
- developer/debug representation
Example¶
class Enemy:
def __repr__(self):
return "Enemy()"
Difference Between str and repr¶
| Method | Purpose |
|---|---|
__str__ |
User-friendly output |
__repr__ |
Developer/debug output |
đ len¶
__len__ controls:
- object length behavior
Example¶
class Inventory:
def __init__(self):
self.items = ["Sword", "Potion"]
def __len__(self):
return len(self.items)
Using len()¶
inventory = Inventory()
print(len(inventory))
Output:
2
âī¸ eq¶
__eq__ controls:
- equality comparison
Example¶
class Player:
def __init__(self, score):
self.score = score
def __eq__(self, other):
return self.score == other.score
Using Equality¶
player1 = Player(10)
player2 = Player(10)
print(player1 == player2)
Output:
True
â add¶
__add__ customizes:
- the + operator
Example¶
class Coins:
def __init__(self, amount):
self.amount = amount
def __add__(self, other):
return Coins(self.amount + other.amount)
Using +¶
c1 = Coins(5)
c2 = Coins(10)
result = c1 + c2
đĻ getitem¶
__getitem__ allows:
- indexing with []
Example¶
class Inventory:
def __init__(self):
self.items = ["Sword", "Potion"]
def __getitem__(self, index):
return self.items[index]
Using Indexing¶
inventory = Inventory()
print(inventory[0])
Output:
Sword
đ iter¶
__iter__ allows:
- iteration with loops
Example¶
class Inventory:
def __init__(self):
self.items = ["Sword", "Potion"]
def __iter__(self):
return iter(self.items)
Using Iteration¶
for item in inventory:
print(item)
đŽ Real 42 Examples¶
Maze String Representation¶
def __str__(self):
Useful for: - ASCII maze printing
Position Comparison¶
def __eq__(self, other):
Useful for: - coordinate comparison - pathfinding
Inventory Length¶
def __len__(self):
Useful for: - item systems
Custom Containers¶
def __getitem__(self, index):
Useful for: - grid systems - tile access
â ī¸ Common Beginner Mistakes¶
â Returning Wrong Types¶
Bad:
def __len__(self):
return "five"
__len__ must return:
- integer
â Forgetting other in eq¶
Wrong:
def __eq__(self):
Correct:
def __eq__(self, other):
â Overcomplicating Dunder Methods¶
Keep behavior: - simple - predictable - readable
â Forgetting Return Values¶
Example:
def __str__(self):
print("Player")
Wrong because:
- __str__ must RETURN a string
đ Best Practices¶
- Keep dunder methods simple
- Return correct types
- Use dunder methods only when useful
- Avoid unnecessary operator overloads
- Focus on readability
đ§ Why Dunder Methods Matter¶
Dunder methods help objects: - behave naturally - integrate with Python syntax - support built-in operations - feel more flexible
They are heavily used in: - frameworks - libraries - games - APIs - custom containers
đ Final Notes¶
Dunder methods are one of the most powerful features of Python OOP.
Understanding them helps create: - cleaner APIs - more intuitive objects - reusable systems - better project architecture
They become increasingly useful in larger and more advanced Python projects.