Python Magic methods

Introduction Reading Time: 10 min

Table of Contents

Description

Magic Methods (also known as Dunder Methods, short for Double Underscore) are special methods with double underscores at the beginning and end (e.g., __init__, __str__, __add__). They are used to customize how Python objects behave with:
Operators (+, >, etc.)
Built-in functions (len(), str())
Object initialization (__init__)
Context managers (with)
They enable operator overloading, custom behavior, and clean class design.

Prerequisites

  • OOP concepts (Classes, Objects)
  • Inheritance and method overriding
  • Operators and built-in functions
  • Understanding of __init__, __str__, etc.

Examples

Here's a simple program in Python:

✅ Basic Magic Methods
class Person:
    def __init__(self, name):
        # Called when object is created
        self.name = name

    def __str__(self):
        # Called when str(obj) or print(obj)
        return f"Person's name is {self.name}"

    def __len__(self):
        # Called when len(obj)
        return len(self.name)

# Creating instance
p = Person("Basha")

print(p)           # Output: Person's name is Basha
print(len(p))      # Output: 5
✅ Operator Overloading using __add__ and __gt__
class Box:
    def __init__(self, volume):
        self.volume = volume

    def __add__(self, other):
        # Overloads + operator
        return Box(self.volume + other.volume)

    def __gt__(self, other):
        # Overloads > operator
        return self.volume > other.volume

    def __str__(self):
        return f"Box({self.volume})"

# Creating Box objects
b1 = Box(10)
b2 = Box(20)

b3 = b1 + b2       # Uses __add__
print(b3)          # Output: Box(30)

print(b2 > b1)     # Output: True (uses __gt__)
✅ Using __eq__, __repr__, and __del__
class Car:
    def __init__(self, brand, price):
        self.brand = brand
        self.price = price

    def __eq__(self, other):
        # Overloads == operator
        return self.brand == other.brand and self.price == other.price

    def __repr__(self):
        # Unambiguous representation
        return f"Car('{self.brand}', {self.price})"

    def __del__(self):
        # Called when object is deleted
        print(f"{self.brand} deleted")

car1 = Car("BMW", 50000)
car2 = Car("BMW", 50000)

print(car1 == car2)    # Output: True
print(repr(car1))      # Output: Car('BMW', 50000)

del car1               # Output: BMW deleted

      

Real-World Applications

Custom classes behaving like built-in types

ORMs (e.g., Django models use magic methods for field access and display)

Data Science Libraries (__getitem__, __setitem__ in pandas, NumPy)

Operator Overloading in mathematical libraries

Context Managers (__enter__, __exit__ used in file handling, DB connections)

Where topic Can Be Applied

Custom object behavior

Data modeling and representation

Overriding built-in functionality

Object lifecycle management

Performance tuning with special object hooks

Resources

Topic video source

A comprehensive video

Watch

Python pdf

pdf on topic

Visit

Interview Questions

What are magic methods in Python?

What is the difference between __str__ and __repr__?

How can you overload the + operator in your custom class?

Which magic method is called when an object is deleted?

What happens if __eq__ is not defined in a class?

How are magic methods used in context managers?

What is the purpose of __getitem__ and __setitem__?

Can we define our own custom magic methods?