Free lab Real Python 3. Zero installs. Your code stays in this browser. Open the playground

Context Managers & the with Statement

15 min 40 XP
Study loop Read Predict Run Tweak Prove Review
Lesson 3 of 6 · View course roadmap
Step 1

Learn the idea

Every time you write with open(...) as f: you're using a context manager — an object that promises to set something up on entry and clean it up on exit, even if the body raises an exception.

The protocol is two dunder methods:

  • __enter__(self) — runs at the start of the with block; its return value is bound by as
  • __exit__(self, exc_type, exc, tb)always runs at the end, exception or not

Files, database transactions, locks, temporary directories, mocked tests — anything with a setup/teardown pair belongs in a context manager. The contextlib.contextmanager decorator lets you write one as a generator: code before yield is the entry, code after is the exit.

Where you'll use this

Database transactions (commit/rollback), file handles, thread locks, temporary directories, test mocks (unittest.mock.patch) and even changing directories — professional code wraps every setup/teardown pair in with so cleanup survives exceptions.

Common mistakes

  • Returning True from __exit__ without meaning to — that swallows the exception and the caller never learns something failed.
  • Doing risky work in __init__ instead of __enter__ — resources should be acquired when the with block starts, not when the object is created.
  • Forgetting that as binds __enter__'s return value — return self unless you have a better handle to give.

Pro tip

One with statement can manage several resources: with open(a) as f, open(b) as g:. And contextlib.suppress(FileNotFoundError) replaces a try/except/pass in one readable line.

Step 2

Try it yourself

Blank · autosaved

The lesson example is loaded and ready — press Run, then change something and run it again. Breaking it is part of learning. Want a clean slate? Tap “New blank”.

PYexample.py
+ Enter to run
Output appears here…
Step 3

Pass the challenge +40 XP

Blank · autosaved

Write a class Tag whose constructor takes a tag name. As a context manager it prints <b> on enter and </b> on exit (for name "b"). Use with Tag("b"): around a line printing bold text.

Target output
<b>
bold text
</b>
PYchallenge.py
Run your code to check it…
Step 4

Check your understanding

1. When does __exit__ run?
2. In a @contextmanager generator, what does the code before yield represent?
Last step

Your notes (saved on this device)

Tip: use and to move between lessons, K to search everything.

Your next ten minutes

Write Python that does something useful.

Start free. No install, no card, no passive video marathon.

Start learning free → Explore the path