Skip to main content
Back to module
Python Fundamentals · Files, Modules, and Packages

Reading and writing files

Reading1hLesson 1 of 3 in this module

Open text files safely with `with`, read CSV data with the csv module and write a summary file.

Why it matters

Data rarely lives inside your program. It arrives as files: instrument exports, spreadsheets saved as CSV, log files, configuration. And results usually need to be saved somewhere for someone else. Reading a file, processing it and writing a summary is one of the most practical things you can do with Python, and it takes only a few lines.

Opening a file with with

with open("notes.txt", "w") as f:
    f.write("first line\n")
    f.write("second line\n")

with open("notes.txt") as f:
    text = f.read()

print(text)
  • open(path, mode) returns a file object. Mode "r" (the default) reads, "w" writes (creating the file, or erasing it if it already exists), and "a" appends to the end.
  • The with block closes the file automatically when the block ends, even if an error happens inside it. Always use with; forgetting to close files can lose data that has not been written yet.
  • write does not add a newline for you. Put "\n" at the end of each line.

A path like "notes.txt" is relative to the folder the program runs in, its working directory. A path such as "data/readings.csv" means "the readings.csv file inside the data folder". If Python says FileNotFoundError, the path or the working directory is usually the problem.

For text that may contain accented letters or symbols, say which encoding to use: open("notes.txt", encoding="utf-8"). UTF-8 is the safe default.

Reading line by line

f.read() gives the whole file as one string. For large files, or when each line is a record, loop over the file object instead:

with open("notes.txt") as f:
    for line in f:
        line = line.strip()      # remove the trailing "\n" and spaces
        if not line:
            continue             # skip blank lines
        print("Line:", line)

f.readlines() returns a list of lines if you need them all at once.

CSV files and the csv module

CSV (comma-separated values) is the most common format for tabular data:

sample,mass_g,temp_c
S-01,12.40,21.5
S-02,11.85,22.0
S-03,12.10,21.0

You could split each line on commas yourself, but real CSV files contain quoted fields with commas inside them, like "Smith, Ada". The standard library's csv module handles all of that:

import csv

with open("samples.csv", newline="") as f:
    reader = csv.DictReader(f)
    rows = list(reader)

print(rows[0])
# {'sample': 'S-01', 'mass_g': '12.40', 'temp_c': '21.5'}

csv.DictReader uses the header row as keys, so each row becomes a dictionary. Notice that every value is a string. Convert before doing maths:

masses = [float(row["mass_g"]) for row in rows]
print(f"Mean mass: {sum(masses) / len(masses):.2f} g")   # Mean mass: 12.12 g

(Opening CSV files with newline="" is what the csv documentation recommends; it stops blank lines appearing on some systems.)

Writing CSV and summary files

csv.writer writes lists as rows, and csv.DictWriter writes dictionaries:

import csv

results = [
    {"sample": "S-01", "status": "ok"},
    {"sample": "S-02", "status": "check"},
]

with open("status.csv", "w", newline="") as f:
    writer = csv.DictWriter(f, fieldnames=["sample", "status"])
    writer.writeheader()
    writer.writerows(results)

A plain text summary is just write calls:

with open("summary.txt", "w") as f:
    f.write(f"samples: {len(masses)}\n")
    f.write(f"mean_mass_g: {sum(masses) / len(masses):.2f}\n")

A worked example: read, summarise, write

import csv

def summarise_csv(in_path, out_path, column):
    with open(in_path, newline="") as f:
        values = [float(row[column]) for row in csv.DictReader(f)]
    with open(out_path, "w") as f:
        f.write(f"count: {len(values)}\n")
        f.write(f"min: {min(values):.2f}\n")
        f.write(f"max: {max(values):.2f}\n")
    return len(values)

summarise_csv("samples.csv", "mass_summary.txt", "mass_g")

Two with blocks, one for reading and one for writing, and a function so you can reuse it on any file and column.

Files in the browser runner

The Do tab runs Python in your browser with its own temporary, in-memory file system. open, csv and with work exactly as on your computer, but the files disappear when you reload the page, and your program cannot see files on your own disk. That is why the exercise first writes a sample CSV file and then reads it back.

Other formats

The same pattern works for other formats in the standard library: the json module reads and writes JSON (json.load(f), json.dump(data, f)), which is common for configuration and web data. For large spreadsheets and analysis, the pandas library (covered in later courses) reads CSV in one line, but it is built on the same ideas.

Common mistakes

  • Opening with "w" when you meant "a". "w" erases the existing file first.
  • Forgetting that CSV values are strings. "12.40" + "11.85" joins text. Convert with float().
  • Missing newlines. f.write("a") then f.write("b") produces ab on one line.
  • Wrong path or working directory. FileNotFoundError usually means the program is running from a different folder than you think.
  • Not using with. Files you forget to close may not be fully written.

Quick recap

  • with open(path, mode) as f: opens a file and closes it for you.
  • Modes: "r" read, "w" write (erases), "a" append.
  • Loop over a file to read it line by line; .strip() each line.
  • csv.DictReader turns rows into dictionaries of strings; convert numbers yourself.
  • f.write(...) writes text; add "\n" yourself.

Try it

In the Do tab you will read a small CSV of sample masses, calculate the count and mean, and write a two-line summary file.

Also in this lesson: