Working with Files
Save and load data for good.
Every night, when Ava closes her laptop, all of her program's data disappears. Variables live in memory, and memory is wiped when the program ends. To keep her orders safe, she must save them to a file on disk. Files are how programs remember things for good.

- Variables vanish when the program ends
- Files stay on the disk
- Goal: save and load Ava's orders
Writing a file
To write a file, open it in write mode, using the with statement. The with block closes the file automatically, even if something goes wrong, so always use it. Then write text into it. Be careful, write mode creates the file if it is missing, and erases it if it exists. We write three order lines, then read them back to check.
with open("orders.txt", "w") as f:
f.write("fern, 2\n")
f.write("ivy, 1\n")
f.write("rose, 5\n")
with open("orders.txt") as f:
print(f.read())fern, 2 ivy, 1 rose, 5
Reading line by line
For big files, read line by line. A file object works in a for loop, giving one line at a time. Each line ends with a newline, so strip it. Here, Ava reads her orders, splits each line at the comma, and adds up the quantities. The mode r is for reading, and it is the default.
total = 0
with open("orders.txt") as f:
for line in f:
name, qty = line.strip().split(", ")
print(name, "x", qty)
total += int(qty)
print("Plants to pack:", total)fern x 2 ivy x 1 rose x 5 Plants to pack: 8
Also uses orders.txt
fern, 2
ivy, 1
rose, 5File modes
The mode decides what you can do. R reads, and fails if the file is missing. W writes, and erases old content. A appends to the end, and keeps what is there. Add a b for binary files, like images. And in text files, say the encoding, utf eight, so special characters work everywhere.
| Mode | Meaning | If file exists | If missing |
|---|---|---|---|
| "r" | read | read it | error |
| "w" | write | erased! | created |
| "a" | append | added to end | created |
| "x" | create only | error | created |
Paths with pathlib
For file paths, use the pathlib module. A path object knows how to join folders on any system, check if a file exists, read text in one call, and list the files in a folder. This is far safer than gluing strings with slashes.
from pathlib import Path
folder = Path("shop")
folder.mkdir(exist_ok=True)
note = folder / "note.txt"
note.write_text("Open 9 to 6")
print(note.exists(), note.name, note.suffix)
print(note.read_text())
print([p.name for p in folder.iterdir()])True note.txt .txt Open 9 to 6 ['note.txt']
CSV: spreadsheet data
CSV files hold tables as plain text, with commas between values. They open in any spreadsheet program. The csv module reads them safely. With DictReader, each row becomes a dictionary, using the header names as keys. Here, Ava totals her sales file, without opening a spreadsheet.
import csv
with open("sales.csv") as f:
rows = list(csv.DictReader(f))
print(rows[0])
total = sum(float(r["price"]) * int(r["qty"]) for r in rows)
print("Revenue:", total){'plant': 'fern', 'price': '9.5', 'qty': '4'}
Revenue: 81.0Also uses sales.csv
plant,price,qty
fern,9.5,4
ivy,7.0,3
rose,11.0,2JSON: data for the web
JSON is the standard format for sharing data between programs and websites. It looks like Python dictionaries and lists. Dump turns Python data into JSON text, and load turns it back. Ava saves her stock as JSON, then loads it in a fresh program, and nothing is lost.
import json
stock = {"fern": 12, "ivy": 4, "tags": ["indoor", "green"]}
with open("stock.json", "w") as f:
json.dump(stock, f, indent=2)
with open("stock.json") as f:
loaded = json.load(f)
print(loaded["fern"], loaded["tags"])
print(open("stock.json").read())12 ['indoor', 'green']
{
"fern": 12,
"ivy": 4,
"tags": [
"indoor",
"green"
]
}A visit counter
Your turn. Write a program that appends the line, new order, to a file called log dot txt, and then reads the file back, and prints every line. Ready? Here is one solution. Append mode first, then a read, with a loop that prints each line.
Append "new order" to log.txt, then read the file and print every line.
Show hint
mode "a" then mode "r"
Show solution
with open("log.txt", "a") as f:
f.write("new order\n")
with open("log.txt") as f:
for line in f:
print(line.strip())new order
Summary
Well done. Your programs can now save and load data. You use with open, you know the modes, you handle paths with pathlib, and you read and write CSV and JSON. Next, what happens when something goes wrong, for example, a missing file? That is the subject of errors.
Key takeaways- with open(...) closes files for you
- pathlib for paths, csv and json for data
- w erases, a appends