5.27. Reading and writing

Files live on disk; Python reaches them through open(), which returns a file object whose methods read and write the underlying bytes.

5.27.1. open and modes

The first argument is the path; the second is the mode – a short string telling Python how the file will be used:

  • "r" – read (default). Opens an existing file for reading.

  • "w" – write. Creates a new file or truncates an existing one to empty.

  • "a" – append. Opens a file for writing at its end without truncating.

  • "b" appended to any of the above ("rb", "wb", "ab") – binary mode. The file’s contents are bytes rather than str.

f = open("notes.txt", "r")
text = f.read()
f.close()

5.27.2. Use a context manager

The pattern above leaks the file handle if anything between open() and close raises. The fix is the with statement (see context managers):

with open("notes.txt") as f:
    text = f.read()

# f is closed here, even if read() failed

This is the standard form – write it this way every time.

5.27.3. Reading

File objects support several read styles:

  • io.IOBase.read() – read the whole file (or N bytes) and return it as a single string (or bytes object).

  • io.IOBase.readline() – read one line, including the trailing "\n".

  • Iterating the file directly yields lines one at a time, with much smaller memory use than reading the whole file at once.

with open("log.txt") as f:
    for line in f:
        print(line.rstrip())

str.rstrip() removes the trailing newline before printing so the output is not double-spaced.

5.27.4. Writing

Open the file in "w" mode and use io.IOBase.write():

with open("out.txt", "w") as f:
    f.write("hello\n")
    f.write("world\n")

io.IOBase.write() does not add a newline – it writes exactly the bytes (or characters, in text mode) you give it.

5.27.5. Text vs binary

Text mode (default, "r" / "w" without "b") decodes incoming bytes into str using a default encoding, and encodes outgoing str back to bytes. Use it for configuration, logs, JSON – anything that is text.

Binary mode ("rb" / "wb") skips the decode step and returns bytes. Use it for images, struct-packed records, network captures – anything where every byte matters and the file is not human-readable.

5.27.6. Listing and removing files

The os module exposes the filesystem operations that are not on the file object itself:

import os

for name in os.listdir("/"):
    print(name)

Catch OSError around these when the file or directory may not be there – the operation is one of the common places exceptions show up in real scripts.