File I/O
📁 File I/O
open() and its modes, the with statement (a context manager) that guarantees files get closed properly, and pathlib — the modern, object-oriented way to work with file paths.
📖 Opening and Reading Files
🔒 The with Statement (Context Managers)
with is a context manager — it guarantees cleanup code runs when the block exits, whether that's normally or via an exception, the same guarantee finally gave you in the last chapter. For files specifically, this is the idiomatic form; plain open()/.close() is considered old-fashioned in real code.
If an exception happens between a manual open() and its matching .close(), the close() line is skipped entirely — the file stays open, holding onto a system resource, for as long as the program keeps running. with closes the file automatically no matter how the block exits, which is why it's always preferred over manual open/close pairs.
✏️ Writing Files
Opening a file in "w" mode truncates it to empty the instant it's opened — before you've written anything new. Opening an existing file you meant to add to using "w" instead of "a" silently destroys everything already in it. Double-check which mode you actually want before running write code against a real file.
🗂️ pathlib
pathlib represents file paths as objects rather than plain strings, with cross-platform path joining and useful methods built in:
Path's / operator is a genuinely nice piece of operator overloading — it replaces manually concatenating strings with slashes (which breaks on Windows anyway, since Windows uses backslashes) with something that reads naturally and works everywhere.
Guaranteed Cleanup: Go vs Kotlin vs Python
| Language | Mechanism |
|---|---|
| Go | defer file.Close() — scheduled to run when the enclosing function returns, regardless of how it returns (including via an error). |
| Kotlin | file.bufferedReader().use { ... } — the use function is Kotlin's own context-manager equivalent, closing the resource automatically at the end of the block. |
| Python | with open(...) as file: — the file closes automatically when the with block ends. |
All three languages converged on the same underlying idea — guaranteed cleanup tied to a block's exit, not left to manual discipline — just with different syntax and a different name for the concept.
open() modes
"r" read, "w" write (truncates!), "a" append.
with statement
Guarantees the file closes automatically, even if an exception occurs.
Reading
.read() (whole file), .readlines() (list of lines), or iterate directly.
pathlib
Path objects, / for joining, .read_text()/.write_text() shortcuts.
💻 Coding Challenges
Challenge 1: Write Then Read
Using with and "w" mode, write three lines to a file called output.txt. Then, in a separate with block using "r" mode, read and print each line (with .strip() to remove trailing newlines).
Goal: Practice the write-then-read round trip using context managers for both.
Challenge 2: Line Counter
Given a text file with several lines, write a function count_lines(filename) that opens it with with and returns how many lines it contains, by iterating over the file object directly rather than calling .readlines().
Goal: Practice line-by-line iteration over a file object as a memory-efficient alternative to reading everything into a list.
Challenge 3: pathlib File Check
Using pathlib, write code that checks whether a file called config.txt exists in a folder called settings. If it exists, print its .suffix; if not, use .write_text() to create it with the contents "default config".
Goal: Practice combining Path's / operator, .exists(), and .write_text() in one realistic check-then-act flow.
🎯 What's Next
Next chapter: Comprehensions & Generators — list/dict/set comprehensions in depth, generator functions, and yield.