Reading & Writing Files

The Course
January 9, 2026
4 min read

Programs become useful when they outlive a single run. Files are the simplest way to make that happen.

Files here are real, but private

The playgrounds on this page write to a filesystem inside your browser tab. The code is exactly what you would run on your own machine, but nothing touches your actual disk, and everything vanishes when the runtime restarts.

Writing

Create a file Python
with open("notes.txt", "w") as file:
    file.write("First line\n")
    file.write("Second line\n")

# Reading it straight back:
with open("notes.txt") as file:
    print(file.read())

Three things to notice:

  • with opens the file and closes it automatically, even if an error is raised inside the block. Always use it.
  • "w" means write, and truncates the file if it already exists.
  • write does not add newlines. You supply them.

The modes

ModeMeaning
"r"Read (the default). Fails if the file is missing.
"w"Write. Creates or empties the file.
"a"Append. Creates if missing, writes to the end.
"x"Create. Fails if the file already exists.
Append instead of overwrite Python
with open("log.txt", "w") as file:
    file.write("start\n")

for step in ["load", "process", "save"]:
    with open("log.txt", "a") as file:
        file.write(f"{step}\n")

with open("log.txt") as file:
    print(file.read())

Reading, three ways

read, readlines, and iteration Python
with open("poem.txt", "w") as file:
    file.write("Roses are red\nViolets are blue\nPython is whitespace\n")

# 1. The whole thing as one string:
with open("poem.txt") as file:
    print(repr(file.read()))

# 2. As a list of lines, newlines included:
with open("poem.txt") as file:
    print(file.readlines())

# 3. Line by line - the memory-friendly way:
with open("poem.txt") as file:
    for number, line in enumerate(file, start=1):
        print(f"{number}: {line.rstrip()}")

Option three is the one to default to. It never holds more than one line in memory, so it works the same on a 3-line file and a 3-gigabyte one. .rstrip() removes the trailing newline that each line carries.

Handling a missing file

When the file is not there Python
def load_settings(path):
    try:
        with open(path) as file:
            return file.read()
    except FileNotFoundError:
        print(f"  {path} not found - using defaults")
        return "theme=light"

print(load_settings("settings.txt"))

Working with tabular data

CSV is the format the world exchanges tables in. Python’s csv module handles the awkward parts — quoted fields, embedded commas — that a naive split(",") gets wrong.

Reading a CSV properly Python
import csv

with open("sales.csv", "w") as file:
    file.write("product,units,price\n")
    file.write("keyboard,3,49.99\n")
    file.write('"widget, large",2,15.00\n')

with open("sales.csv") as file:
    reader = csv.DictReader(file)
    total = 0
    for row in reader:
        line_total = int(row["units"]) * float(row["price"])
        total += line_total
        print(f"{row['product']:15} {line_total:8.2f}")

print(f"{'TOTAL':15} {total:8.2f}")

DictReader uses the header row as keys, so row["price"] beats row[2] for readability — and survives someone reordering the columns.

Everything read from a file is text

row["units"] is "3", not 3. The same conversion rule as input() on Day 1 applies here, for the same reason.

Writing a CSV

Writing rows out Python
import csv

rows = [
    {"name": "Ada", "score": 95},
    {"name": "Alan", "score": 88},
]

with open("scores.csv", "w", newline="") as file:
    writer = csv.DictWriter(file, fieldnames=["name", "score"])
    writer.writeheader()
    writer.writerows(rows)

with open("scores.csv") as file:
    print(file.read())

newline="" is the one incantation to remember — without it, Windows produces a blank line between every row.

Exercise

Word frequency from a file

Write the paragraph to a file, then read it back and print the five most common words with their counts. Lower-case everything and strip punctuation with strip(".,!?").

text = """the sun rose and the birds sang
the day was bright and the air was clear
the sun warmed the stones"""

with open("morning.txt", "w") as file:
    file.write(text)

# Your code here
Show one solution
text = """the sun rose and the birds sang
the day was bright and the air was clear
the sun warmed the stones"""

with open("morning.txt", "w") as file:
    file.write(text)

counts = {}
with open("morning.txt") as file:
    for line in file:
        for word in line.lower().split():
            word = word.strip(".,!?")
            counts[word] = counts.get(word, 0) + 1

ranked = sorted(counts.items(), key=lambda pair: (-pair[1], pair[0]))
for word, count in ranked[:5]:
    print(f"{word:8} {count}")

Reading line by line and counting as you go means this same code would work unchanged on a file too large to fit in memory.

What you learned

  • with open(path, mode) as file: opens and reliably closes a file.
  • "r" reads, "w" truncates, "a" appends, "x" refuses to overwrite.
  • Iterating a file yields lines, one at a time, with newlines attached.
  • FileNotFoundError is the one to catch around reads.
  • Use the csv module for tabular data; everything read is text.
Last updated on January 9, 2026

Was this article helpful?

Your response is saved on this device.