Python course module guide: File handling and resource safety
Python context managers define a reliable boundary around setup and cleanup. The with statement makes resource ownership visible and ensures cleanup is attempted whether the block succeeds, returns early or raises an exception.
What you will learn
- Understand
__enter__and__exit__. - Use files and database transactions safely.
- Create context managers with
contextlib. - Avoid suppressing failures accidentally.
Why the with statement matters
Resources such as files, database connections and locks have a lifecycle: acquire, use and release. If cleanup depends on remembering a final method call, an early return or exception can leave the resource open. A context manager places cleanup in the protocol rather than in the programmer’s memory.
from pathlib import Path
path = Path("students.csv")
with path.open("r", encoding="utf-8") as handle:
first_line = handle.readline()
print(handle.closed) # True
The Python file handling guide covers modes, encodings, CSV, JSON and common I/O errors. Context managers provide the cleanup boundary around those operations.
The context manager protocol
An object used by with implements __enter__() and __exit__(). Enter returns the value assigned after as. Exit receives exception information and performs cleanup.
class ManagedReport:
def __init__(self, path):
self.path = path
self.handle = None
def __enter__(self):
self.handle = open(self.path, "w", encoding="utf-8")
return self.handle
def __exit__(self, exc_type, exc_value, traceback):
if self.handle is not None:
self.handle.close()
return False
with ManagedReport("summary.txt") as report:
report.write("completed\n")
Returning False allows an exception to continue. Returning True suppresses it. Suppression should be rare and deliberate because silent failures are difficult to diagnose.
Create a context manager with contextlib
from contextlib import contextmanager
from time import perf_counter
@contextmanager
def measured_block(label):
started = perf_counter()
try:
yield
finally:
elapsed = perf_counter() - started
print(f"{label}: {elapsed:.4f}s")
with measured_block("daily report"):
total = sum(range(100_000))
The code before yield performs setup, and the finally block performs cleanup. Use the class form when a reusable object has meaningful state or methods; use @contextmanager for a focused setup/cleanup sequence.
Database transaction boundaries
import sqlite3
with sqlite3.connect("training.db") as connection:
connection.execute(
"UPDATE enrolments SET status = ? WHERE id = ?",
("confirmed", 42),
)
The connection context manages transaction commit or rollback behavior, but connection-closing behavior should be checked for the library you use. Do not assume every context manager performs every kind of cleanup. The Python SQLite expense tracker provides a larger CRUD and transaction example.
Control multiple resources
from pathlib import Path
with (
Path("source.txt").open(encoding="utf-8") as source,
Path("clean.txt").open("w", encoding="utf-8") as target,
):
for line in source:
if line.strip():
target.write(line)
Grouping resources expresses that they belong to one operation. For a dynamic number of resources, contextlib.ExitStack can manage callbacks and context managers in one stack.
Context managers in API and web code
Network sessions, tracing spans, temporary directories and request-scoped database connections all use similar lifecycle ideas. In the Python API pagination and retries guide, a session is explicitly created and closed. The Flask REST API project uses request-context cleanup for SQLite connections.
Common context-manager mistakes
- Opening a resource outside the
withblock and losing ownership clarity. - Using the resource after the block has closed it.
- Returning
Truefrom__exit__without intending to suppress an exception. - Doing heavy business logic inside setup or cleanup methods.
- Assuming transaction management also closes a connection.
- Testing only the successful path and never checking cleanup after failure.
Practice exercise: safe export
Build a context manager that writes a report to a temporary filename. If the block succeeds, rename the temporary file to its final name. If it fails, remove the incomplete temporary file and allow the original exception to continue. Test both paths and make the cleanup behavior explicit.
Context manager FAQs
Does with catch exceptions?
The context manager receives exception information during exit. The exception continues unless the manager deliberately suppresses it by returning a true value.
Can one with statement manage several resources?
Yes. Multiple context managers can appear in one statement. They are exited in reverse order, which supports predictable nested cleanup.
Should every class be a context manager?
No. Implement the protocol when an object has a clear acquisition and release lifecycle. Ordinary data objects usually do not need it.
What happens when setup fails?
If __enter__ raises an exception, the block never begins and that same manager’s __exit__ is not called. Setup code must therefore clean up anything it acquired before the failure. When several steps are dynamic, ExitStack can register cleanup as each resource succeeds.
Official reference: Python contextlib documentation.
Learn Python with guided practice in Visakhapatnam
These concepts become useful when you apply them in exercises, assignments and reviewed projects. Explore Python training in Vizag for the complete curriculum, classroom and online learning options, and current batch details.
Python module learning path
Continue through the related practical guides in this course-module series: