Module 16 — File I/O
Reading and writing files safely — text, and structured data with CSV.
Prerequisite: Module 15 — Error & Exception Handling
After this lesson, you will be able to
- Open, read, and write text files safely using a with block
- Explain the common file modes: r, w, a
- Read and write CSV files with the csv module
Concept & Syntax
So far every program's data has disappeared the moment it stops running. File I/O (input/
output) is how a program persists data — saving it to disk, and reading it back later. Python opens files with
open(), but the safe, idiomatic way to do it is inside a with block, which
automatically closes the file for you, even if an error happens partway through.
with open("notes.txt", "r", encoding="utf-8") as f:
content = f.read()
with open("notes.txt", "w", encoding="utf-8") as f:
f.write("New content")Examples
Writing a text file Very Easy
with open("notes.txt", "w", encoding="utf-8") as f:
f.write("First line\n")
f.write("Second line\n")Mode "w" creates the file if it doesn't exist, or overwrites it completely if it does. The with block closes the file automatically when it's done.
Reading a whole file Easy
with open("notes.txt", "r", encoding="utf-8") as f:
content = f.read()
print(content)Mode "r" (the default) opens for reading. read() returns the entire file's contents as one string.
Reading line by line Intermediate
with open("notes.txt", "r", encoding="utf-8") as f:
for line in f:
print("Line:", line.strip())Looping directly over an open file gives you one line at a time — memory-efficient for large files. strip() removes the trailing newline.
Appending instead of overwriting Real World
with open("notes.txt", "a", encoding="utf-8") as f:
f.write("Third line\n")Mode "a" (append) adds to the end of the file instead of erasing what's already there.
Reading and writing CSV Challenge
import csv
with open("scores.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerow(["name", "score"])
writer.writerow(["Ada", 92])
with open("scores.csv", "r", encoding="utf-8") as f:
reader = csv.DictReader(f)
for row in reader:
print(row["name"], row["score"])csv.writer writes rows as comma-separated values; csv.DictReader reads each row back as a dictionary, keyed by the header row.
Visual Explanation
💡 Why does this work?
Read the concept explanation above again slowly, line by line — every keyword there maps directly onto a line of code in the examples. If it still doesn't click, re-run the traced example (if this lesson has one) one step at a time.
🔍 What happens internally? (advanced)
Under the hood, Python compiles your source into bytecode and runs it on a virtual machine (the CPython interpreter). Variables are names in a namespace dictionary pointing at objects in memory — which is exactly what the memory panel in the tracer above is showing you.
Common Mistakes
Opening a file without a with block (or forgetting to close it) can leave data unwritten or the file locked by your program.
f = open("notes.txt", "w")
f.write("Hello")
# forgot f.close() — data may not be saved yetwith open("notes.txt", "w") as f:
f.write("Hello")
# file is guaranteed to be closed here- Always use a with block to open files — it closes them automatically, even on error.
- Specify encoding="utf-8" explicitly, since default encodings vary across operating systems.
- Use mode "a" only when you genuinely want to add to existing content — "w" erases everything first.
- Prefer the csv module over manually splitting lines on commas — it correctly handles quoted fields.
Exercise & Challenge
Exercise 1 — Predict the output
with open("notes.txt", "a") as f:
f.write("World")If notes.txt already contains 'Hello', what will it contain after this code runs?
🏆 Challenge
Write a program that writes 5 numbers (1 through 5) to a file, one per line, then reads them back and prints their sum.
- Write with mode "w"
- Read the file back and convert each line to int()
- Print the total sum
💡 Need a hint?
int(line.strip()) removes the trailing newline before converting.
🔍 Show a sample solution
with open("numbers.txt", "w") as f:
for n in range(1, 6):
f.write(f"{n}\n")
total = 0
with open("numbers.txt", "r") as f:
for line in f:
total += int(line.strip())
print(total)Quiz
Answer every question, then submit to see your score and explanations.
1. What does opening a file in mode "w" do if the file already exists?
2. Why is a with block preferred when working with files?
3. What does csv.DictReader give you for each row?
Summary
- open(filename, mode) opens a file; always wrap it in a with block.
- Mode "r" reads, "w" overwrites, "a" appends.
- Looping over an open file yields one line at a time.
- The csv module handles reading and writing tabular data correctly, including quoted fields.