Context Managers
Context managers are one of Python's most elegant and powerful tools — used everywhere from file handling, database transactions, network requests, locks, concurrency, and resource safety.
Learn Python, JavaScript, Java and more with free interactive lessons, real projects and AI-powered help. Beginner-friendly.
Part of the free Python course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
What You'll Learn in This Lesson
If you've ever written with open("file.txt") as f: …you've already used a context manager.
✔ How to create them using generator functions (contextlib.contextmanager)
✔ How real systems use them for safe resource handling
✔ How to build production-grade context managers
✔ How to combine context managers with decorators & advanced design patterns
A context manager controls a setup phase and a cleanup phase.
The moment execution enters the with block, the context manager prepares a resource. When the block exits — even if an error occurs — the resource is cleaned up.
Let's build a simple context manager that logs entering/exiting:
This pattern exists in ORMs like SQLAlchemy & Django:
For simpler cases, Python provides a shortcut.
Locks are native context managers. This pattern protects shared memory in concurrent programs.
You can combine context managers with decorators to automatically wrap function execution:
If __exit__ returns True, exceptions are swallowed.
Never suppress runtime errors silently in real systems.
✔ How to combine decorators and context managers
✔ How to create production-grade resource managers
You can now build and use context managers for any resource lifecycle — files, databases, locks, timers, and more.
Up next: Generators — produce values lazily for memory-efficient data pipelines.
Practice quiz
Which two phases does a context manager control?
- Compile and run
- Read and write
- A setup phase and a cleanup phase
- Import and export
Answer: A setup phase and a cleanup phase. A context manager manages a setup phase (on entry) and a cleanup phase (on exit).
Which two methods must a class-based context manager define?
- __enter__ and __exit__
- __init__ and __del__
- __aenter__ and __aexit__
- open and close
Answer: __enter__ and __exit__. Class-based context managers implement __enter__ (entry) and __exit__ (cleanup).
The value returned by __enter__ becomes what?
- The exception type
- The return value of the whole block
- Always None
- The variable bound by 'as' in the with statement
Answer: The variable bound by 'as' in the with statement. __enter__'s return value is assigned to the 'as' variable in the with statement.
Does __exit__ run if an exception is raised inside the with block?
- No, exceptions skip cleanup
- Yes, __exit__ always runs (it's like a finally)
- Only if you catch the exception first
- Only for KeyboardInterrupt
Answer: Yes, __exit__ always runs (it's like a finally). __exit__ runs whether the block finishes normally or raises — like a finally clause.
How does __exit__ suppress (swallow) an exception that occurred in the block?
- By returning True
- By raising it again
- By returning None
- By calling sys.exit()
Answer: By returning True. Returning True from __exit__ tells Python to suppress the exception.
In a @contextmanager generator, where does the cleanup code go?
- Before the yield
- In a separate function
- After the yield
- In __init__
Answer: After the yield. Setup runs before yield; the cleanup code runs after the yield.
How many times must a @contextmanager generator yield?
- Zero times
- Exactly once
- Twice
- As many as you like
Answer: Exactly once. It must yield exactly once; zero or multiple yields raise a RuntimeError.
What is the modern way to use two context managers in a single with statement?
- with A() as a: with B() as b:
- with A() and B():
with A() as a, B() as b: manages both on one line, avoiding deep nesting.
What does contextlib.ExitStack let you do?
- Run code faster
- Manage a dynamic, runtime-determined number of context managers
- Suppress all exceptions
- Replace try/except
Answer: Manage a dynamic, runtime-determined number of context managers. ExitStack enters a variable number of context managers and exits them all (in reverse) at block end.
Are threading locks usable directly as context managers with 'with lock:'?
- No, you must wrap them
- Only async locks support it
- Yes, locks are native context managers
- Only with ExitStack
Answer: Yes, locks are native context managers. Locks implement the context manager protocol, so 'with lock:' acquires and releases automatically.