Reading and Writing Files
File I/O crosses a boundary between program state and an external filesystem. Make the data format, encoding, mode, and failure behavior explicit.
Resource lifetime
Use a context manager so the file is closed even when an exception occurs:
from pathlib import Path
path = Path("notes.txt")
with path.open("r", encoding="utf-8") as handle:
for line in handle:
process(line.rstrip("\n"))
Iterating over the file streams lines. read() and readlines() load the
remaining content into memory and should be reserved for bounded inputs.
rstrip("\n") removes a line ending without also discarding meaningful spaces
as an unrestricted strip() would.
Text and binary modes
Text mode decodes bytes into str; binary mode returns bytes unchanged.
text = path.read_text(encoding="utf-8")
payload = Path("image.bin").read_bytes()
Specify an encoding for durable text rather than depending on a machine's locale
default. Newline translation is another text-mode behavior; pass newline= when
a file format requires precise control.
The main modes are:
| Mode | Meaning | Existing file |
|---|---|---|
r | read | required |
w | write | truncated |
a | append | preserved |
x | exclusive create | must not exist |
Add b for binary mode or + for combined reading and writing. Treat w as a
destructive operation.
Structured formats
Use a format-aware library rather than hand-built string splitting:
import json
with Path("settings.json").open("r", encoding="utf-8") as handle:
settings = json.load(handle)
Use csv for delimited data and open CSV files with newline="" as its
documentation recommends. Parsing does not validate business meaning; check the
resulting schema, ranges, and required fields separately.
Failures and safer replacement
Handle only errors for which the program has a recovery policy, such as
FileNotFoundError, PermissionError, decoding errors, or invalid format data.
Do not collapse all failures into an empty result.
For important output, write a temporary file in the same directory, flush and close it, then replace the destination. A same-filesystem rename can prevent readers from observing a partially written file, but crash durability may also require filesystem-specific synchronization. Atomic replacement does not solve concurrent-writer coordination.