File I/O & JSON
File I/O & JSON
Opening Files
open(path, mode) returns a file object. Always use a with statement so the file is closed automatically:
with open("data.txt", "r") as f:
content = f.read()Common Modes
| Mode | Meaning |
|---|---|
"r" | Read (default) — file must exist |
"w" | Write — creates or truncates |
"a" | Append — creates or appends |
"x" | Exclusive create — fails if file exists |
"b" | Binary modifier ("rb", "wb") |
"t" | Text modifier (default) |
"+" | Read + write ("r+", "w+") |
Reading Methods
f.read() # entire file as one string
f.readline() # one line (including newline)
f.readlines() # list of all lines
for line in f: # iterate line by line (memory-efficient)
...Writing Methods
f.write("Hello\n") # write a string
f.writelines(["line1\n", "line2\n"]) # write a list of stringspathlib.Path
pathlib provides an object-oriented API for paths — far more readable than os.path string manipulation:
from pathlib import Path
p = Path("data") / "reports" / "2024.txt" # / operator builds paths
p.parent # Path("data/reports")
p.stem # "2024"
p.suffix # ".txt"
p.exists() # bool
p.read_text() # shortcut for open().read()
p.write_text("hello")
list(p.parent.glob("*.txt")) # find all .txt filesJSON
JSON (JavaScript Object Notation) is the most common data-interchange format.
import json
# Python → JSON string
data = {"name": "Alice", "scores": [95, 87, 92]}
s = json.dumps(data, indent=2) # pretty-printed
# JSON string → Python
parsed = json.loads(s)
# Write to file
with open("data.json", "w") as f:
json.dump(data, f, indent=2)
# Read from file
with open("data.json") as f:
loaded = json.load(f)Python ↔ JSON type mapping: dict ↔ object, list ↔ array, str ↔ string, int/float ↔ number, True/False ↔ true/false, None ↔ null.
CSV Basics
import csv
# Writing
with open("people.csv", "w", newline="") as f:
writer = csv.DictWriter(f, fieldnames=["name", "age"])
writer.writeheader()
writer.writerows([{"name": "Alice", "age": 30}])
# Reading
with open("people.csv") as f:
reader = csv.DictReader(f)
for row in reader:
print(row["name"], row["age"])Always pass newline="" when opening CSV files for writing to prevent extra blank lines on Windows.
Code Examples
from pathlib import Path
import tempfile, os
# Use a temp directory for demo
tmp = Path(tempfile.mkdtemp())
# --- Writing ---
poem_path = tmp / "poem.txt"
lines = [
"Roses are red,\n",
"Violets are blue,\n",
"Python is great,\n",
"And so are you!\n",
]
with open(poem_path, "w") as f:
f.writelines(lines)
print("Written:", poem_path.name)
# --- Reading entire file ---
with open(poem_path) as f:
content = f.read()
print("\nFull content:\n" + content)
# --- Reading line by line (memory-efficient) ---
print("Lines with numbers:")
with open(poem_path) as f:
for i, line in enumerate(f, 1):
print(f" {i}: {line}", end="")writelines() writes a list of strings without adding separators — include \n yourself. Iterating over a file object reads line by line without loading the whole file into memory, which is critical for large files.
import json
# Python dict → JSON string
user = {
"id": 1,
"name": "Alice",
"email": "alice@example.com",
"scores": [95, 87, 92, 88],
"active": True,
"address": None,
}
json_str = json.dumps(user, indent=2)
print("JSON string:")
print(json_str)
# JSON string → Python dict
parsed = json.loads(json_str)
print("\nParsed name:", parsed["name"])
print("Average score:", sum(parsed["scores"]) / len(parsed["scores"]))
print("Active:", parsed["active"])
print("Address:", parsed["address"])json.dumps() converts a Python object to a JSON string. indent=2 produces human-readable output. json.loads() parses a JSON string back to Python. Notice Python's True/None become JSON's true/null automatically.
from pathlib import Path
import csv, tempfile
tmp = Path(tempfile.mkdtemp())
# --- pathlib ---
data_dir = tmp / "data"
data_dir.mkdir()
txt_file = data_dir / "notes.txt"
txt_file.write_text("Hello from pathlib!")
print("Exists:", txt_file.exists())
print("Stem: ", txt_file.stem)
print("Suffix:", txt_file.suffix)
print("Parent:", txt_file.parent.name)
print("Content:", txt_file.read_text())
# --- CSV write ---
csv_path = tmp / "employees.csv"
employees = [
{"name": "Alice", "dept": "Engineering", "salary": 95000},
{"name": "Bob", "dept": "Marketing", "salary": 72000},
{"name": "Carol", "dept": "Engineering", "salary": 88000},
]
with open(csv_path, "w", newline="") as f:
writer = csv.DictWriter(f, fieldnames=["name", "dept", "salary"])
writer.writeheader()
writer.writerows(employees)
# --- CSV read ---
print("\nEmployee report:")
with open(csv_path) as f:
for row in csv.DictReader(f):
print(f" {row['name']} ({row['dept']}): ${int(row['salary']):,}")pathlib.Path uses / to join path components and provides read_text()/write_text() shortcuts. csv.DictWriter writes rows from dicts using the fieldnames list as column headers. csv.DictReader reads each row as a dict, making column access by name natural.
Quick Quiz
1. What file mode should you use to append to an existing file without truncating it?
2. What does json.dumps() return?
3. Why should you pass newline='' when opening a CSV file for writing?
4. Which pathlib method reads an entire text file into a string in one call?
Was this lesson helpful?