← Back to Python Course | Chapter 7: OOP | Lesson 9 of 11

Python Magic Methods

What are Magic Methods?

Magic methods (also called dunder methods, for their double underscores like __init__) are special hooks Python calls automatically for built-in operations -- defining __init__ lets you customize object construction, while other dunders let you customize printing, comparison, arithmetic, and more.

Example: What are Magic Methods?

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

p = Point(1, 2)
print(p.x, p.y)

Operator Overloading

Defining __add__(self, other) on a class lets the + operator work on your own objects -- write two Vector objects and v1 + v2 calls v1.__add__(v2) behind the scenes, letting you return a new Vector with summed components instead of Python raising a TypeError.

Example: Operator Overloading

python
class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __add__(self, other):
        return Vector(self.x + other.x, self.y + other.y)

v = Vector(1, 2) + Vector(3, 4)
print(v.x, v.y)

Comparison Magic Methods

Overloading __eq__ lets you define what '==' means for your class (like comparing two Point objects by their x/y coordinates rather than by identity), and __lt__ defines '<' so that built-ins like sorted() and min() know how to order your objects.

Example: Comparison Magic Methods

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

print(Point(1, 2) == Point(1, 2))

Length and Container Methods

Defining __len__ makes len(my_object) work on your custom class, and __getitem__ lets it support square-bracket indexing (my_object[0]) -- together these two are often enough to make a custom class usable anywhere a list or dict would be expected.

Example: Length and Container Methods

python
class Basket:
    def __init__(self, items):
        self.items = items
    def __len__(self):
        return len(self.items)
    def __getitem__(self, index):
        return self.items[index]

b = Basket(["apple", "banana"])
print(len(b), b[0])

Making Objects Callable

Implementing __call__ lets you invoke an instance directly like a function -- my_object() -- which is useful for objects that wrap some configurable behavior, such as a class that remembers settings and then runs a computation when called.

Example: Making Objects Callable

python
class Multiplier:
    def __init__(self, factor):
        self.factor = factor
    def __call__(self, x):
        return x * self.factor

times3 = Multiplier(3)
print(times3(10))

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.