What are Python's magic (dunder) methods and how do I use them?

· Category: Python Programming

Short answer

Magic methods (double-underscore or "dunder" methods) let you define how objects behave with built-in operations. Common ones include __init__, __str__, __repr__, __eq__, __len__, and arithmetic operators like __add__.

Steps

  1. Implement __repr__ for an unambiguous developer-friendly representation.
  2. Implement __str__ for a readable end-user representation.
  3. Implement comparison and arithmetic operators for intuitive object behavior.
class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __repr__(self):
        return f"Vector({self.x}, {self.y})"

    def __str__(self):
        return f"({self.x}, {self.y})"

    def __eq__(self, other):
        if not isinstance(other, Vector):
            return NotImplemented
        return self.x == other.x and self.y == other.y

    def __add__(self, other):
        return Vector(self.x + other.x, self.y + other.y)

v1 = Vector(1, 2)
v2 = Vector(3, 4)
print(v1 + v2)   # (4, 6)

Tips

  • __repr__ should ideally be a valid Python expression that could recreate the object.
  • Implement __hash__ if you define __eq__ and want to use the object in sets or as dict keys.
  • Context managers use __enter__ and __exit__; iteration uses __iter__ and __next__.

Common issues

  • Returning NotImplemented (not raising an exception) allows Python to try the reverse operation.
  • Defining __eq__ without __hash__ makes an object unhashable, preventing its use in sets and dict keys.
  • Infinite recursion can occur in __repr__ or __str__ if they inadvertently trigger themselves.