Learning

Context Managers

Context Managers

Context Manager Protocol

python
class FileHandler: def __init__(self, filename, mode): self.filename = filename self.mode = mode self.file = None def __enter__(self): self.file = open(self.filename, self.mode) print(f'Opened {self.filename}') return self.file def __exit__(self, exc_type, exc_val, exc_tb): if self.file: self.file.close() print(f'Closed {self.filename}') if exc_type: print(f'Exception: {exc_val}') return False # Don't suppress exceptions with FileHandler('test.txt', 'w') as f: f.write('Hello!') # Output: # Opened test.txt # Closed test.txt

contextlib.contextmanager

python
from contextlib import contextmanager @contextmanager def my_open(filename, mode): f = open(filename, mode) try: print(f'Opening {filename}') yield f # Value for 'as' variable finally: f.close() print(f'Closed {filename}') with my_open('test.txt', 'r') as f: content = f.read()

suppress() Utility

python
from contextlib import suppress with suppress(FileNotFoundError): open('nonexistent.txt', 'r') print('This won\'t print if file missing') print('Continued anyway!') # Always prints # Equivalent to: try: open('nonexistent.txt', 'r') except FileNotFoundError: pass

Timer Context Manager

python
import time class Timer: def __enter__(self): self.start = time.perf_counter() return self def __exit__(self, *args): self.elapsed = time.perf_counter() - self.start print(f'Elapsed: {self.elapsed:.4f}s') with Timer() as t: sum(range(1000000)) print(f'Stored: {t.elapsed:.4f}s')

Nested Context Managers

python
with open('in.txt') as fin, open('out.txt', 'w') as fout: fout.write(fin.read())

Redirecting stdout

python
import sys from contextlib import redirect_stdout with open('output.txt', 'w') as f: with redirect_stdout(f): print('This goes to file, not console')
Key Rules
  • •__enter__() sets up the resource and returns the value for 'as' variable
  • •__exit__(exc_type, exc_val, exc_tb) handles cleanup — receives exception info if any was raised
  • •Return True from __exit__ to SUPPRESS the exception, False to let it propagate
  • •@contextmanager turns a generator function into a context manager — yield the resource, cleanup in finally
  • •Use suppress() to silently handle specific exceptions without try/except blocks
  • •Always use context managers for files, locks, database connections, and network sessions
Your Task

Create a `Timer` class-based context manager that records start time in __enter__, calculates elapsed in __exit__, and prints the elapsed time. Create a `@contextmanager` function `temporary_file(content)` that creates a temp file with content, yields the file path, and deletes the file in finally block. Create a `DatabaseConnection` context manager that prints 'Connected' in __enter__ and 'Disconnected' in __exit__. Demonstrate all three.

EditorPython · JSX
PreviewUpdates on Run Tests
Loading preview…
Tests
Should define Timer with __enter__ and __exit__
Timer should use time.perf_counter()
Should use @contextmanager decorator
temporary_file should have finally block
Should define DatabaseConnection class
Should demonstrate with statement for all three