Skip to content
Go back

Mastering Context Managers in Python: Beyond 'with open()'

In this stage of the course, we dove into one of Python’s most elegant features: context managers.

Everyone has used with open(filename) — but few understand what really happens under the hood. This part of the course uncovered that mystery.


Step 1 — What Is a Context Manager?

A context manager is any object that defines two special methods:

def __enter__(self):
    # Setup logic (open file, acquire resource)
    return something

def __exit__(self, exc_type, exc_value, traceback):
    # Cleanup logic (close file, release resource)

This is what the with statement uses behind the scenes.


Step 2 — Building One From Scratch

We built a context manager that times a code block:

import time

class Timer:
    def __enter__(self):
        self.start = time.time()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.end = time.time()
        print(f"Elapsed: {self.end - self.start:.2f} seconds")

Used like this:

with Timer():
    # Some expensive operation
    result = sum(i * i for i in range(10**6))

Step 3 — Handling Exceptions Gracefully

The __exit__ method can control whether exceptions are suppressed:

def __exit__(self, exc_type, exc_val, traceback):
    if exc_type:
        print("An error occurred:", exc_val)
    return True  # Suppress exception

Step 4 — Using contextlib

To avoid writing boilerplate classes, Python includes contextlib:

from contextlib import contextmanager

@contextmanager
def timer():
    start = time.time()
    yield
    end = time.time()
    print(f"Elapsed: {end - start:.2f} seconds")

Same behavior, less code.


Lessons Learned

Next up: we’ll explore exception handling patterns in depth — and how Python’s control flow and call stack really behave.


Share this post on:

Previous Post
Designing Exceptions and Message Handling in Python
Next Post
Building a Stack from Scratch in Python