Course outline · 0% complete

0/27 lessons0%

Course overview →

Files: reading and writing from zero

lesson 8-0 · ~11 min · 20/27

Programs that remember

Everything you have computed so far vanished the moment the program ended, because variables live only in memory. Real software must persist data: save the game, keep a log, read yesterday's records back in. The operating system's unit of durable storage is the file, a named sequence of bytes on disk, and Python's built-in open() is the door to it.

f = open("todo.txt", "w")   # open for writing
f.write("buy milk\n")
f.close()

open(path, mode) returns a file object, your handle on the open file. The mode string declares your intent:

ModeMeaning
"r"read (the default)
"w"write, erasing whatever the file held
"a"append to the end

write puts text into the file exactly as given, so you add the \n line breaks yourself. close() tells the operating system you are done, which flushes any buffered text to disk and frees the handle. Forgetting it risks losing the last writes.

Writing a file, then reading it back

The first half creates the file and writes two lines, the second half reopens it for reading and prints each line.

f = open("todo.txt", "w")
f.write("buy milk\n")
f.write("call ada\n")
f.close()

f = open("todo.txt")
for line in f:
    print(line.strip())
f.close()

Output

buy milk
call ada

Two details carry most of the weight here. Every write call has to supply its own \n, because write adds nothing for you, unlike print. And every line read back includes that newline character, which is why line.strip() appears before printing. Without it each line would arrive with its newline and print would add another, doubling the blank space.

The close() calls matter too. Until a file is closed, written data may still be sitting in a buffer rather than on disk. The next lesson replaces this manual bookkeeping with a with block that cannot forget.

Three ways to read

  • f.read() returns the whole file as one string, fine for small files.
  • f.readlines() returns a list of the lines.
  • for line in f: streams one line at a time, the professional default.

The loop works because a file object is an iterator over its lines, the lesson 4-1 protocol again. Two consequences follow from what you already know about iterators:

  • Lines arrive one at a time, so a 10-gigabyte log file never has to fit in memory.
  • The iterator is one-shot: a second loop over the same open file gets nothing, because the read position is already at the end.

Every line keeps its trailing \n, so strip() is the usual companion, and int(line) works directly because int ignores surrounding whitespace.

Round-tripping numbers through a file

Numbers have to become text on the way out and numbers again on the way back in. This code writes three numbers one per line, then reopens the file and totals them.

nums = [3, 9, 27]

f = open("nums.txt", "w")
for n in nums:
    f.write(str(n) + "\n")
f.close()

f = open("nums.txt")
total = 0
for line in f:
    total += int(line)
f.close()
print(total)

Output

39

write only accepts strings, so each number goes through str(n) and the newline is appended by hand. Passing 3 directly would raise a TypeError.

The file is opened twice, once with "w" to create and write it, and once with the default "r" mode to read it. On the way back, int(line) handles the trailing newline without complaint, because int ignores surrounding whitespace, so int("27\n") is simply 27.

The mode that destroys data

If notes.txt already holds 100 lines, open("notes.txt", "w") erases all of them immediately.

Mode "w" truncates. The old content is gone the moment open returns, even if you never write a single byte afterwards and even if the program crashes on the next line. Nothing warns you and nothing asks for confirmation.

ModeOpens forIf the file exists
"r"reading (the default)left untouched
"w"writingcontents erased
"a"appendingwrites go to the end
"x"writing a new fileraises FileExistsError

An accidental "w" is one of the classic ways to destroy data. When you mean to add to a file, the mode is "a", and it is worth reading that character twice before running anything.