Reading a Text File
Everything so far vanished the moment a program ended, and every piece of data had to be typed in. Files change both. Reading a text file takes three lines of Python, and one of those lines, starting with with, makes sure the file is closed properly even if something goes wrong while you are reading it.
Think of borrowing a book from a library. You take it out, read it, and return it at the door. with is the rule that the book goes back at the door, whatever happened while you were reading.
A File to Read
Make a plain text file called notes.txt in your python-course folder, with the three lines below, the same way you made hello.py in Chapter 1.
Buy milk Call the dentist Book train tickets
open and with
The open function connects your program to a file and gives back an object for reading it. Writing it inside with gives that object a name, here f, for the length of the indented block, and closes the file automatically when the block ends. The encoding argument says how to turn the bytes on disk into text; the section below explains it. The read method gives back the whole file as one string.
with open("notes.txt", encoding="utf-8") as f: text = f.read() print(text)
Buy milk Call the dentist Book train tickets
The blank line at the end of that output is not a mistake. The file ends with a line break, and print adds one more.
Line by Line
More often you want one line at a time. A for loop over the open file gives exactly that. Each line keeps the line break at its end, and print adds another, so the output comes out double-spaced. The strip method from Chapter 2 removes the line break, and the gaps disappear.
with open("notes.txt", encoding="utf-8") as f: for line in f: print(line)
Buy milk Call the dentist Book train tickets
with open("notes.txt", encoding="utf-8") as f: for number, line in enumerate(f, start=1): print(number, line.strip())
1 Buy milk 2 Call the dentist 3 Book train tickets
The second version also numbers the lines. The built-in enumerate hands out a count alongside each item, starting wherever you ask, and the two names after for unpack the pair, exactly as with a dictionary's items in Chapter 6.
Text Encoding
A file on disk is a sequence of bytes, numbers from 0 to 255. An encoding is the rule for turning those bytes into letters. Plain English letters look the same in almost every encoding, which is why this can go unnoticed for a long time. Letters with accents, other alphabets and symbols like the euro sign are stored differently by different encodings, and reading with the wrong one produces garbled text or an error.
UTF-8 is the encoding that can represent every language and is used almost everywhere today. From Python 3.15 it is the default when you open a text file, on every system; before that, Windows used an older, local encoding by default. This book still writes encoding="utf-8" on every open. The habit costs a few characters and keeps your program behaving the same on older Pythons, where the default was different.
The File That Is Not There
Ask to open a file that is not there and Python raises a FileNotFoundError, with the name it looked for at the end of the message. Nine times out of ten the file does exist, but in a different folder from the one the program looked in. Topic 3 of this chapter is entirely about that.
with open("todo.txt", encoding="utf-8") as f: print(f.read())
Traceback (most recent call last):
File "/Users/you/python-course/missing.py", line 1, in <module>
with open("todo.txt", encoding="utf-8") as f:
~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: 'todo.txt'
- "Lines come without their line break." Each line keeps the line break at its end. strip removes it.
- "with is optional decoration." Without it you must close the file yourself, and an error halfway through would skip the closing. with closes it every time.
- "Garbled accents mean the file is damaged." Usually the file is fine and was read with the wrong encoding.
- "FileNotFoundError means the file does not exist." It means the file is not at the path the program used. Check the folder first.
- Reading files is how a program starts working with real data instead of values typed into it.
- with is the pattern for everything that must be released after use: files now, network connections and more later.
Knowledge Check
What does with guarantee when you open a file?
- The file is closed when the block ends, even after an error
- The file is read completely before the block begins
- The file is created first if it does not already exist
- The file cannot be changed by any other programs while it is open
Why is the output double-spaced when you print each line of a file?
- The file was saved with an empty line between each pair of lines
openadds a line break to every line it reads- Each line keeps its own line break, and print adds another
- A for loop always prints an empty line between rounds
What is a text encoding?
- A password that keeps the file's contents private from others
- A way of compressing text so the file takes up less space
- The name of the program that created the file
- The rule for turning the bytes on disk into letters
Why does this book write encoding="utf-8" even on Python 3.15?
- Because Python 3.15 refuses to open files without it
- It keeps the program behaving the same on older Pythons
- Because UTF-8 makes files load faster than other encodings
- Because UTF-8 is the only encoding Python can read
You got correct