Python & Django

Understanding Context Managers in Python

August 17, 2026
2 min read
6 views

If you've ever written with open('file.txt') as f:, you've used a context manager. But what's actually happening under the hood, and why should you care?

The Problem They Solve

Resources like files, network connections, and locks need to be cleaned up after use — even if something goes wrong. Doing this manually is error-prone:

f = open('data.txt')
data = f.read()
f.close()  # Never runs if read() throws an exception!

Context managers guarantee cleanup happens, no matter what:

with open('data.txt') as f:
    data = f.read()
# file is closed automatically, even on error

How They Work: __enter__ and __exit__

Any object implementing __enter__ and __exit__ can be used with with. Python calls __enter__ when entering the block and __exit__ when leaving it — including when an exception is raised.

class ManagedResource:
    def __enter__(self):
        print("Acquiring resource")
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("Releasing resource")
        # Return True to suppress the exception, False/None to propagate it
        return False

with ManagedResource() as r:
    print("Using resource")

Output:

Acquiring resource
Using resource
Releasing resource

The Easier Way: contextlib

Writing a full class for simple cases is overkill. The contextlib module's @contextmanager decorator lets you write a context manager as a generator function:

from contextlib import contextmanager

@contextmanager
def timer(label):
    import time
    start = time.time()
    try:
        yield
    finally:
        print(f"{label}: {time.time() - start:.4f}s")

with timer("database query"):
    run_query()

Everything before yield acts as __enter__; everything after (typically in a finally block) acts as __exit__.

Common Real-World Uses

  • File I/O: open() — automatic closing
  • Locks: threading.Lock() — automatic release
  • Database transactions: commit on success, rollback on error
  • Temporary state changes: swapping config values and restoring them afterward
  • Suppressing exceptions: contextlib.suppress(FileNotFoundError)

Multiple Context Managers

You can combine several in one with statement:

with open('input.txt') as infile, open('output.txt', 'w') as outfile:
    outfile.write(infile.read().upper())

Key Takeaway

Context managers turn "please remember to clean this up" into "this is guaranteed to be cleaned up." Whenever you find yourself writing matching setup/teardown code — especially with try/finally — that's a signal you probably want a context manager instead.

Topics

Python
MAR

MD Abdur Rahim

Senior Python Developer helping teams ship backend systems and AI products — Django, FastAPI, LangChain, RAG pipelines, and cloud infra that hold up in production.

Comments (0)

Minimum 3 characters

0/1000

No comments yet

Be the first to share your thoughts!

Enjoyed this article?

Subscribe to my newsletter to receive updates on new blog posts, tech insights, and development tips.

No spam. Unsubscribe anytime. Read our Privacy Policy.