💡 Advanced Python Concepts
Estimated reading: 4 minutes 272 views

Python Context Managers Explained – __enter__, __exit__, and contextlib

Introduction – Why Use Context Managers?

In Python, you often need to acquire and release resources safely. Think of:

  • Opening and closing files
  • Acquiring and releasing locks
  • Managing database connections
  • Timing or logging blocks of code

Context managers provide a clean, readable way to manage such resources automatically—using the with statement.

In this guide, you’ll learn:

  • What context managers are and how they work
  • How the with statement simplifies resource management
  • How to create custom context managers using classes or decorators
  • Real-world use cases and best practices

What Is a Context Manager?

A context manager is a Python object that defines how to set up and clean up a resource.

It must implement two methods:

__enter__(self) → Called at the start of the `with` block  
__exit__(self, exc_type, exc_val, exc_tb) → Called at the end, even on errors

Built-in Context Manager Example – File Handling

with open("sample.txt", "w") as f:
    f.write("Hello, context managers!")

Automatically closes the file after writing—even if an exception occurs.

Equivalent to:

f = open("sample.txt", "w")
try:
    f.write("Hello")
finally:
    f.close()

Custom Context Manager Using a Class

class ManagedFile:
    def __init__(self, filename):
        self.filename = filename

    def __enter__(self):
        self.file = open(self.filename, "w")
        return self.file

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.file.close()

with ManagedFile("log.txt") as f:
    f.write("Logging entry")

Resource is acquired on __enter__() and released on __exit__().


🧙‍♂️ Context Managers with contextlib

from contextlib import contextmanager

@contextmanager
def managed_file(name):
    f = open(name, "w")
    try:
        yield f
    finally:
        f.close()

with managed_file("output.txt") as file:
    file.write("Written with contextlib")

Use @contextmanager for simpler and cleaner code when using generators.


Multiple Context Managers in One Line

with open("in.txt") as infile, open("out.txt", "w") as outfile:
    data = infile.read()
    outfile.write(data)

Use comma-separated context managers to manage multiple resources.


Exception Handling in Context Managers

class SafeBlock:
    def __enter__(self):
        print("Entering block")
    
    def __exit__(self, exc_type, exc_value, traceback):
        print("Exiting block")
        if exc_type:
            print(f"Error: {exc_value}")
        return True  # suppresses exception

with SafeBlock():
    raise ValueError("Oops")  # Handled silently

Real-World Use Cases

Use CaseDescription
File I/OOpen/read/write files
Thread locksAcquire/release threading/multiprocessing locks
Database connectionsOpen/close cursor or session
Timers/ProfilersMeasure time around a code block
Temporary directory/filesCreate and clean up temp resources

️ Example – Context Manager Timer

import time
from contextlib import contextmanager

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

with timer():
    time.sleep(1.5)

Output:

Elapsed time: 1.50s

Best Practices

Do This Avoid This
Use with for resources like files, locksManually handling open/close
Use contextlib for simple wrappersCreating classes when a function will do
Always clean up in __exit__ or finallyIgnoring cleanup logic
Handle exceptions in __exit__()Letting exceptions crash without cleanup

Summary – Recap & Next Steps

Context managers in Python offer a clean and Pythonic way to manage resources. They reduce boilerplate and ensure your code stays safe, concise, and readable.

Key Takeaways:

  • Use with statements to manage setup and teardown
  • Custom context managers implement __enter__ and __exit__
  • Use contextlib for decorator-based managers
  • Great for files, locks, connections, timers, and logging

Real-World Relevance:
Used in file systems, database clients, thread management, testing, and resource cleanup frameworks.


FAQ – Python Context Managers

What does a context manager do?

It handles setup and teardown logic automatically via __enter__ and __exit__.

Can I use multiple with statements?

Yes. Use a comma-separated list or nested blocks.

Is __exit__ called on exception?

Yes. It runs even if an exception occurs—great for cleanup.

When should I use contextlib?

Use it when your context logic fits well into a generator (setup, yield, cleanup).

What if I forget to close a file?

You risk a resource leak. Always prefer the with statement to handle it safely.


Share Now :
Share

Python Context Managers

Or Copy Link

CONTENTS
Scroll to Top