← Back to Python series
⚙️
Intermediate
open · read · write · with · CSV · JSON · pathlib

Week 6 — File I/O

Persist data to disk with Python's file I/O. Read and write plain text, CSV, and JSON files using context managers, the csv module, and json module.

fileopencsvjsonpathlibcontext manager
Duration
2.5 hours
Level
📊 Intermediate
Prerequisite
🎯 Week 5
OUTCOME
Build a student grade manager that loads/saves CSV and exports JSON reports

What you'll learn

  • 1Open, read, write, and append files with open()
  • 2Use context managers (with statement) for safe file handling
  • 3Parse and write CSV files with the csv module
  • 4Serialize and deserialize JSON with the json module
  • 5Navigate paths with pathlib

1. Text Files

python
# Write
with open("notes.txt", "w", encoding="utf-8") as f:
    f.write("Line 1\n")
    f.write("Line 2\n")

# Read all at once
with open("notes.txt", encoding="utf-8") as f:
    text = f.read()

# Read line by line (memory-efficient)
with open("notes.txt", encoding="utf-8") as f:
    for line in f:
        print(line.rstrip())
💡

Always specify encoding="utf-8" to avoid platform-dependent encoding surprises.

2. CSV Files

python
import csv

# Write CSV
with open("students.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=["name","score"])
    writer.writeheader()
    writer.writerows([{"name":"Alice","score":90},{"name":"Bob","score":82}])

# Read CSV
with open("students.csv", encoding="utf-8") as f:
    reader = csv.DictReader(f)
    for row in reader:
        print(row["name"], row["score"])

3. JSON Files

python
import json

data = {"name": "Alice", "scores": [90, 85, 92], "active": True}

# Serialize to file
with open("data.json", "w") as f:
    json.dump(data, f, indent=2)

# Deserialize from file
with open("data.json") as f:
    loaded = json.load(f)
print(loaded["scores"])  # [90, 85, 92]

4. Common Mistakes

  1. Opening without "with" — file may not be closed on error. Always use "with open(...) as f:".
  2. Writing CSV without newline="" → blank rows on Windows.
  3. json.dumps() returns a string; json.dump() writes to a file. Easy to mix up.

💻 Examples

Run these examples and check the output yourself.

01_text_rw.pyRead and write a log file
CODE
from datetime import datetime
LOGFILE = "app.log"

def log(msg):
    ts = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    with open(LOGFILE, "a", encoding="utf-8") as f:
        f.write(f"[{ts}] {msg}\n")

def read_log():
    with open(LOGFILE, encoding="utf-8") as f:
        return f.read()

log("Application started")
log("User logged in: alice")
print(read_log())
02_grade_csv.pyGrade manager with CSV load/save
CODE
import csv
from pathlib import Path

FILE = Path("grades.csv")

def load():
    if not FILE.exists(): return []
    with FILE.open(encoding="utf-8") as f:
        return list(csv.DictReader(f))

def save(records):
    with FILE.open("w", newline="", encoding="utf-8") as f:
        w = csv.DictWriter(f, fieldnames=["name","score"])
        w.writeheader(); w.writerows(records)

records = load()
records.append({"name": "Diana", "score": "95"})
save(records)
print(load())

📝 Exercises

Try them yourself first, then open the solution to compare.

Exercise 1

Config File Manager

Goal: Read and write a JSON config file with default fallback.

Requirements
  • load_config(path) → dict (returns {} if file missing)
  • save_config(path, data) → writes JSON with indent=2
  • update_config(path, key, value) → load, update key, save
Toggle solution
SOLUTION
import json
from pathlib import Path

def load_config(path):
    p = Path(path)
    if not p.exists(): return {}
    return json.loads(p.read_text())

def save_config(path, data):
    Path(path).write_text(json.dumps(data, indent=2))

def update_config(path, key, value):
    cfg = load_config(path)
    cfg[key] = value
    save_config(path, cfg)

update_config("config.json", "theme", "dark")
print(load_config("config.json"))
Example code / lecture materials

All lecture materials and example code are openly available on GitHub.

View on GitHub ↗