Python Intermediate and Advanced

Python Intermediate_012:Python’s Magic Methods in Classes(Overview)

codeaddict 2025. 4. 5. 21:31

If you’ve been playing with Python classes, you might’ve heard of “magic methods” — those special methods with double underscores (like __init__). They’re not as mysterious as they sound — they just let you customize how your objects behave. In this post, we’ll cover what they are, why they matter, and give a quick peek at some common ones. Next time, we’ll dig into each one deeper. Let’s get started!

1. What Are Magic Methods?

Magic methods (or “dunder” methods, short for “double underscore”) are built-in Python methods you can define in your classes. They control how objects work with Python’s operators, functions, and features — like addition, printing, or comparisons. You don’t call them directly; Python does it behind the scenes.

For example:

  • __init__ sets up a new object.
  • __str__ decides what print() shows.

They’re “magic” because they hook into Python’s core behavior, letting you tweak it without extra code.

2. Why Use Them?

  • Customization: Make objects act how you want (e.g., adding two objects with +).
  • Readability: Control what shows up when you print an object.
  • Power: Tap into Python’s built-in tools (like len() or ==) for your classes.

They’re optional — if you don’t define them, Python uses defaults. But adding them makes your classes more useful.

3. A Quick Tour of Common Magic Methods

Here’s a rundown of some key ones. We’ll keep it simple — just what they do and a basic example. Full details come in the next lesson!

__init__(self, …)

  • What It Does: Runs when you create a new object. Sets up initial values.

Example:

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

p = Point(3, 4)  # __init__ sets x=3, y=4

__str__(self)

  • What It Does: Defines what print() shows for your object.

Example:

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

p = Point(3, 4)
print(p)  # Outputs: Point(3, 4)

__add__(self, other)

  • What It Does: Lets you use + to add two objects.

Example:

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

p1 = Point(1, 2)
p2 = Point(3, 4)
p3 = p1 + p2  # p3 is Point(4, 6)

__eq__(self, other)

  • What It Does: Decides if two objects are equal with ==.

Example:

class Point:
    def __eq__(self, other):
        return self.x == other.x and self.y == other.y

p1 = Point(1, 2)
p2 = Point(1, 2)
print(p1 == p2)  # True

__len__(self)

  • What It Does: Lets len() work on your object.

Example:

class Bag:
    def __init__(self, items):
        self.items = items
    def __len__(self):
        return len(self.items)

b = Bag([1, 2, 3])
print(len(b))  # 3

4. How They Fit Together

Here’s a tiny class using a few at once:

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __str__(self):
        return f"({self.x}, {self.y})"
    def __add__(self, other):
        return Point(self.x + other.x, self.y + other.y)

p1 = Point(1, 2)
p2 = Point(3, 4)
p3 = p1 + p2
print(p3)  # Outputs: (4, 6)

5. What’s Next?

This is just the start — Python has a bunch of magic methods to explore. They’re called dunder methods because of the double underscores (__) around their names. “Dunder” is shorthand for “double under” — a nickname Python folks use since they’re special methods tied to how Python works under the hood.

Why the Double Underscores?

You might wonder: why __len__ instead of just len? The double underscores mark these as reserved names — Python’s way of saying, “Hey, these are mine, but you can customize them.” They’re like hooks built into the language. When you write len(obj), Python doesn’t call a plain len method — it looks for __len__ in your class and runs that. The __ keeps them separate from your own method names (like calculate or show), avoiding clashes.

How Do You Use Them?

You define them in your class with the exact name (like def __len__(self):), add self as the first argument (since they’re class methods), and tell Python what to do. Python calls them automatically when you use the matching feature:

  • obj + other → __add__
  • print(obj) → __str__
  • len(obj) → __len__

Why Not Just len?

If it was just len, it’d conflict with the built-in len() function — or any method you might name len for something else. The __len__ name is a contract: Python knows to look for it when len() is called, and you get to decide what “length” means for your object. It’s about giving you control while keeping things organized.

The Big List

Here’s a rundown of the most important dunder methods:

  • __init__(self, …): Creates a new object.
  • __str__(self): Controls print() output.
  • __repr__(self): Gives a detailed string for debugging.
  • __add__(self, other): Handles +.
  • __sub__(self, other): Handles -.
  • __mul__(self, other): Handles *.
  • __truediv__(self, other): Handles /.
  • __eq__(self, other): Checks ==.
  • __lt__(self, other): Checks <.
  • __gt__(self, other): Checks >.
  • __le__(self, other): Checks <=.
  • __ge__(self, other): Checks >=.
  • __ne__(self, other): Checks !=.
  • __len__(self): Works with len().
  • __getitem__(self, key): Enables obj[key].
  • __setitem__(self, key, value): Enables obj[key] = value.
  • __del__(self): Runs when an object is deleted.
  • __call__(self, …): Lets you call an object like a function.

Each one ties to a specific Python feature, and the __ makes them distinct. In the next tutorials, I’ll break down the most important ones — like __init__, __str__, __add__, and __len__ — with examples and tips. For now, try adding a couple to your own class and see what you can make happen!