๐with Statement, __enter__/__exit__, contextlibLESSON~15 min
Context Managers: with Statement, enter/exit, contextlib
The with statement solves a pervasive problem: ensuring that resources are always cleaned up, even when exceptions occur. Files must be closed, locks must be released, database transactions must be committed or rolled back. Context managers make this automatic.
The with Statement
The with statement:
Calls __enter__() on the context manager
Binds the return value to the as variable (if present)
Executes the body
Calls __exit__() โ always, even if an exception occurred
enter and exit
To make a class a context manager, implement these two methods:
exit Parameters
__exit__(self, exc_type, exc_val, exc_tb) receives three arguments:
exc_type: the exception class, or None if no exception
exc_val: the exception instance, or None
exc_tb: the traceback object, or None
Return True to suppress the exception (swallow it โ execution continues after the with block). Return False or None to let it propagate.
The @contextmanager decorator lets you write context managers as generator functions. Everything before yield is the __enter__ logic; the yielded value is bound to as; everything after yield is the __exit__ logic:
To handle exceptions in a @contextmanager, wrap the yield in try/except:
contextlib.suppress
contextlib.suppress(*exceptions) is a pre-built context manager that silently suppresses specified exceptions:
contextlib.nullcontext
nullcontext(enter_result=None) is a no-op context manager โ useful when a context manager is optional:
Multiple Context Managers
You can open multiple context managers in one with statement:
Timing Example
A common use case โ measuring how long a block takes:
Knowledge Check
What does `__exit__` returning `True` do?
In a `@contextmanager` generator, where is the `__enter__` logic placed?