Part 5 of 6 · Chapter 1 of 4

Reading and Writing Outside the Program

Everything so far has lived inside the program and vanished the moment it stopped running. Write a line to an actual file on disk, close it properly, and read the same line back in a program that starts fresh.

Intermediate9 min read

Everything so far has lived inside the program and vanished the moment it stopped running. Write a line to an actual file on disk, close it properly, and read the same line back in a program that starts fresh.

Opening a file is not the same as using it safely

Terminal
$ >>> f = open("notes.txt", "w")$ >>> f.write("first line\n")$ 11$ >>> f.close()

open("notes.txt", "w") creates the file if it does not exist yet, or empties it if it does — the "w" means write mode. write() returns the number of characters written, which is easy to ignore and easy to forget you are ignoring.

with closes the file even when something goes wrong

with wraps the open file in a block that closes it automatically the moment the block ends — including when an error is raised partway through, which a manual close() call would never reach.

Terminal
$ >>> with open("notes.txt", "w") as f:$ ...     f.write("first line\n")$ ...     f.write("second line\n")$ ...$ >>> f.closed$ True

Reading uses the same shape, with "r" in place of "w" — and it is the default, so it can be left out entirely.

Terminal
$ >>> with open("notes.txt") as f:$ ...     contents = f.read()$ ...$ >>> print(contents)$ first line$ second line

Paths behave differently depending on where the program runs from

"notes.txt" is a relative path — Python looks for it relative to wherever the program was started from, not relative to the .py file itself. Run the same script from two different folders, and it can read two entirely different files, or fail to find one at all.

Terminal
$ >>> from pathlib import Path$ >>> Path("notes.txt").resolve()$ PosixPath('/Users/you/project/notes.txt')$ >>> Path("notes.txt").exists()$ True

Key takeaways

  • open("notes.txt", "w") creates or empties a file; "r", the default, reads it instead.
  • Nothing is guaranteed to reach disk until close() runs, and a crash mid-program can skip it.
  • with closes the file automatically when the block ends, even if an error interrupts it partway through.
  • A relative path like "notes.txt" is resolved against where the program was started, not where the .py file lives — Path(...).resolve() shows exactly which file that is.