The `with` statement ensures cleanup code runs even if an exception occurs, most commonly for files.
python
with open("data.txt") as f:
contents = f.read()
# file is automatically closed here, even on errorYou can build your own context manager with a class implementing `__enter__`/`__exit__`, or more simply with `contextlib.contextmanager`:
python
from contextlib import contextmanager
@contextmanager
def timer():
import time
start = time.time()
yield
print(f"took {time.time() - start:.3f}s")
with timer():
total = sum(range(1_000_000))