Code Snippets
/

Custom Context Manager (Class-Based)

Custom Context Manager (Class-Based)

A class-based context manager defines `__enter__` and `__exit__` so the object can be used in a `with` block. It is the right shape when the resource has setup, teardown, AND state you want to expose to the body (file handles, DB connections, locks). This entry shows the basic skeleton, an exception-aware variant, and the gotchas around return values from `__exit__`.

Python
Medium
3 snippets
py-context-managers
py-magic-methods
py-standard-library

217 views

5

class Timer:
    """Measure how long the with-block took, in seconds."""

    def __enter__(self):
        import time
        self.start = time.perf_counter()
        return self  # value bound by `as` in the with-statement

    def __exit__(self, exc_type, exc_value, traceback):
        import time
        self.elapsed = time.perf_counter() - self.start
        # Return None / False so any exception is re-raised.

with Timer() as t:
    total = sum(i * i for i in range(100_000))

print('sum:', total)
print(f'elapsed: {t.elapsed:.4f}s')

__enter__ runs at the top of the with block; whatever it returns is bound to the as target. __exit__ always runs when the block ends, whether by falling off the bottom or by an exception. The three arguments (exc_type, exc_value, traceback) are all None on a clean exit and describe the exception otherwise. Returning None (or any falsy value) lets the exception propagate, which is what 99% of context managers want. The pattern is the right tool whenever 'do X before, undo X after' has to survive every exit path.