Back to all snippets
Library/Python/Custom Context Manager
pythonadvancedcontext-managerpatternsresourcesasync

How to implement Custom Context Manager in Python

Build reusable resource management with Python context managers

Quick Answer

Use `@contextlib.contextmanager` with a `yield` for simple cases, or implement `__enter__`/`__exit__` on a class for complex cases — both enable the `with` statement for guaranteed cleanup.

Code Snippet

1from contextlib import contextmanager
2import time
3
4# 1. Generator-based context manager (simplest approach)
5@contextmanager
6def timer(label: str = 'Block'):
7    start = time.perf_counter()
8    try:
9        yield
10    finally:
11        elapsed = time.perf_counter() - start
12        print(f'{label} took {elapsed:.4f}s')
13
14with timer('Data processing'):
15    time.sleep(0.1)  # your code here
16
17# 2. Class-based context manager
18class DatabaseConnection:
19    def __init__(self, url: str):
20        self.url = url
21        self.conn = None
22
23    def __enter__(self):
24        print(f'Connecting to {self.url}')
25        self.conn = object()  # replace with real connection
26        return self.conn
27
28    def __exit__(self, exc_type, exc_val, exc_tb):
29        print('Closing connection')
30        self.conn = None
31        return False  # re-raise exceptions
32
33with DatabaseConnection('postgresql://localhost/mydb') as conn:
34    pass  # use conn here
35
36# 3. Async context manager
37from contextlib import asynccontextmanager
38
39@asynccontextmanager
40async def async_timer(label: str):
41    start = time.perf_counter()
42    try:
43        yield
44    finally:
45        print(f'{label}: {time.perf_counter() - start:.4f}s')

What is Custom Context Manager?

Context managers let you manage resources — database connections, file handles, locks, timers — in a clean, exception-safe way using the with statement. You can create your own using either the class-based approach (__enter__ and __exit__) or the simpler generator-based approach with contextlib.contextmanager.

How It Works

  1. 1`@contextmanager` turns a generator function into a context manager — code before `yield` runs on `__enter__`, code in `finally` runs on `__exit__`.
  2. 2The class-based approach implements `__enter__` (setup, returns the resource) and `__exit__` (cleanup, receives exception info).
  3. 3Returning `False` from `__exit__` re-raises any exception; returning `True` suppresses it.
  4. 4`@asynccontextmanager` works the same way but with `async def` and `await` for asyncio.

Common Use Cases

  • Database connections - Auto-commit or rollback transactions on success or failure
  • Temporary directory - Create and clean up temp files automatically
  • Thread locks - Acquire and release locks safely around critical sections
  • HTTP sessions - Open and close network sessions with guaranteed cleanup

Key Benefits

  • Guarantees resource cleanup even when exceptions are raised
  • Readable, intention-revealing code with the with statement
  • Async version works seamlessly with asyncio
  • Eliminates repetitive try/finally boilerplate

Common Mistakes to Avoid

  • Forgetting `try/finally` around `yield` in `@contextmanager` — without `finally`, exceptions skip the cleanup code.
  • Raising exceptions in `__exit__` — this replaces the original exception, hiding the root cause.
  • Not yielding in `@contextmanager` — the generator must yield exactly once; yielding zero or more than once raises `RuntimeError`.

Quick Tips

  • Click the "Copy" button above to copy the code to your clipboard
  • This code is production-ready and can be used in your projects immediately
  • Check out related snippets below for more python examples

Frequently Asked Questions

When should I use the class-based approach vs @contextmanager?

Use `@contextmanager` for simple cases where the generator syntax is cleaner. Use the class-based approach when you need to store state across `__enter__` and `__exit__`, inherit from the context manager, or reuse it multiple times.

About This Python Code Snippet

This free python code snippet for custom context manager is production-ready and copy-paste friendly. Whether you are building a web app, API, or frontend interface, this advanced-level example will help you implement custom context manager quickly and correctly.

All snippets in the Snippetly library follow python best practices and are tested for real-world use. You can adapt this code to work with React, Vue, Node.js, or any project that uses python.

Tags: context-manager, patterns, resources, async  | Language: python  | Difficulty: advanced  | Category: Python

Build Your Own Snippet Library

Organise your team's code snippets with Snippetly. Share knowledge and boost productivity across your organisation.