07.3 - Context Managers & pathlib
Theory 20 min Intermediate
The with Statement
The with statement guarantees that cleanup code runs even if an exception occurs:
# Without with — resource leak if exception!
f = open("data.txt")
data = f.read()
f.close() # might not run!
# With with — always clean
with open("data.txt") as f:
data = f.read()
# f.close() is called automatically
The with statement calls __enter__() on entry and __exit__() on exit.
Custom Context Manager with contextlib
The easiest way to write a context manager:
from contextlib import contextmanager
@contextmanager
def timer(label=""):
"""Context manager that times a block of code."""
import time
start = time.perf_counter()
try:
yield # execution enters the with block here
finally:
elapsed = time.perf_counter() - start
print(f"{label}: {elapsed*1000:.2f}ms")
with timer("Data processing"):
data = [x**2 for x in range(1_000_000)]
# Data processing: 45.23ms
@contextmanager
def managed_file(path, mode="r", **kwargs):
"""Context manager for file operations with error handling."""
f = None
try:
f = open(path, mode, **kwargs)
yield f
except FileNotFoundError:
print(f"File not found: {path}")
yield None
finally:
if f:
f.close()
contextlib.suppress
from contextlib import suppress
# Instead of try/except for FileNotFoundError
with suppress(FileNotFoundError):
import os
os.remove("temp_file.txt") # no error if file doesn't exist
Multiple Context Managers
# Old style
with open("input.txt") as fin:
with open("output.txt", "w") as fout:
fout.write(fin.read())
# Modern style (parentheses)
with (
open("input.txt") as fin,
open("output.txt", "w") as fout
):
fout.write(fin.read())
pathlib Deep Dive
from pathlib import Path
# Basic operations
p = Path("/home/alice/documents/report.pdf")
p.name # "report.pdf"
p.stem # "report"
p.suffix # ".pdf"
p.suffixes # [".pdf"]
p.parent # Path("/home/alice/documents")
p.parents[1] # Path("/home/alice")
# Build paths with /
config = Path.home() / ".config" / "myapp" / "settings.json"
# Check existence
p.exists()
p.is_file()
p.is_dir()
p.is_symlink()
# File info
p.stat().st_size # file size in bytes
p.stat().st_mtime # modification time
# Read/Write
text = p.read_text(encoding="utf-8")
p.write_text("content", encoding="utf-8")
raw = p.read_bytes()
p.write_bytes(raw)
# Directory operations
Path("new_dir").mkdir(exist_ok=True)
Path("nested/dirs").mkdir(parents=True, exist_ok=True)
# Glob patterns
list(Path(".").glob("*.py")) # Python files here
list(Path(".").rglob("*.py")) # Python files recursively
list(Path(".").glob("**/*.json")) # JSON files recursively
# Rename and delete
p.rename("new_name.pdf")
p.unlink() # delete file
p.rmdir() # delete empty directory
Key Vocabulary
| Term | Definition |
|---|---|
| Context manager | Object implementing __enter__ and __exit__ |
@contextmanager | Decorator turning a generator into a context manager |
contextlib.suppress | Context manager that silences specified exceptions |
yield | Pause point in a @contextmanager function |
pathlib.Path | Object-oriented path representation |
glob() | Pattern matching to find files (e.g., *.py) |
rglob() | Recursive glob — searches subdirectories too |
Summary
- The
withstatement calls__enter__and always calls__exit__, even on exceptions @contextmanagerwithyieldis the simplest way to write context managerscontextlib.suppress(ExcType)silently ignores specific exceptions- Open multiple context managers in one
withblock using parentheses (Python 3.10+) pathlib.Pathreplacesos.pathwith a clean OOP interface- Use
Path.glob()andPath.rglob()for file discovery with patterns
📄️ 07.1 - File I/O
Open, read, write, and append text files using Python's built-in open() function and context managers
📄️ 07.2 - CSV & JSON
Read and write CSV datasets and JSON configuration files using Python's standard library
📄️ 07.3 - Context Managers
Write custom context managers with contextlib, navigate the filesystem with pathlib, and manage resources safely
📄️ Lab - Module 07
Build a data pipeline that reads CSV, processes records, and outputs JSON reports
📄️ Quiz - Module 07
30 questions on file I/O, CSV, JSON, pathlib, and context managers