__enter__ and __exit__

RoadmapsPython

Overview

The `__enter__` and `__exit__` dunder methods define the context manager protocol. This is the set of methods an object must implement to support the `with` statement. Think of them as automatic setup and teardown hooks for an object's lifecycle. - `__enter__(self)`: Executes setup logic before the block starts. It RETURNS the value assigned to the `as` variable (often `self` or `None`). If it fails, the exception propagates and `__exit__` is skipped. - `__exit__(self, exc_type, exc_val, traceback)`: Executes teardown logic when the block ends. It RETURNS a boolean indicating if an exception should be suppressed. If it fails, the new exception replaces the original one. When `with Obj() as x:` runs, Python calls `Obj.__enter__()` and assigns the result to `x`. When the block ends, normally or via an exception, Python calls `Obj.__exit__()`. class SilentFail: def __enter__(self): return self def __exit__(self, exc_type, exc_val, traceback): # Returning True swallows the exception! return True with SilentFail(): raise ValueError("This will be hidden") A common trap is accidentally swallowing exceptions by returning `True` (or a truthy value) from `__exit__`. This completely suppresses the error, making debugging difficult. Simpler ways to write context managers are covered fully in `contextmanager-decorator`.

They guarantee cleanup (like closing files or releasing locks) happens reliably, even if the code inside the block crashes. This replaces repetitive `try`/`finally` blocks.

Where used: Custom database sessions, Temporary file management, Resource locks

Why learn this

Code walkthrough

class Timer:
  def __enter__(self):
    print('Start')
    return self
  def __exit__(self, t, v, tb):
    print('End')

with Timer():
  print('Working')

Focus: with Timer():

Aha moment

class FakeFile:
  def __enter__(self):
    return 'data'
  def __exit__(self, *args):
    pass

with FakeFile() as f:
  print(type(f).__name__)

Prediction: What type is printed?

Common guess: FakeFile

The variable `f` gets whatever `__enter__` returns, not necessarily the context manager instance itself. Since it returns the string `'data'`, `f` is a string.

Common mistakes

Glossary

suppressed
Preventing an error or exception from stopping the program, effectively hiding or neutralizing it. Example: `return True`
hooks
Special functions or methods that let you insert your own code into the normal sequence of a program's execution. Example: `def __enter__(self):`

Recall questions

Understanding checks

What is printed to the console?

Enter Value Exit

`__enter__` is called first, printing `'Enter'`. Its return value `'Value'` is bound to `d`. The block prints `d` (`'Value'`), and finally `__exit__` runs, printing `'Exit'`.

What is printed to the console?

Caught: ValueError Done

The `ValueError` is caught by `__exit__`, which prints it. Because `__exit__` returns `True`, the exception is suppressed and execution continues to print `'Done'`.

Practice tasks

Modify Exception Handling

Given this context manager, change it so that it suppresses ONLY `KeyError` exceptions, and lets everything else propagate.

Challenge

A Simple Transaction Context

Write a `Transaction` context manager that takes a dictionary. In `__enter__`, it should return a shallow copy of the dictionary. In `__exit__`, if no exception occurred, it should update the original dictionary with the copy's contents.

Continue learning

Previous: Class Creation and Instantiation

Previous: try/except with specific exception types

Next: contextlib.contextmanager decorator

Next: Async context managers

Return to Python Roadmap