Paths and folders with pathlib
`Path` objects join folder and file names with `/`, take names apart, create folders, read and write whole files, and list a folder's files with `glob`.
- Join path pieces with
/and read a path'sname,stemandsuffix - Create folders with
mkdir(parents=True, exist_ok=True)and check files withexists() - List the files that match a pattern with
glob, in a predictable order
So far a path has been a string like "out/delivered.txt". Strings work until you need to take a path apart (what's the file's extension?), join pieces safely, or ask questions (does this file exist? which files are in this folder?).
from pathlib import Path gives you Path objects. / joins pieces: Path("exports") / "orders.csv". A path knows its name (orders.csv), stem (orders) and suffix (.csv), can check exists(), create a folder with mkdir, and read or write a whole small file with read_text and write_text (each takes encoding= like open).
Run each example to see what it prints. Running examples doesn't count toward progress.
from pathlib import Path report = Path("exports") / "2024-12" / "orders.csv" print(report) print(report.name, report.stem, report.suffix) print(report.exists()) folder = Path("exports") / "2024-12" folder.mkdir(parents=True, exist_ok=True) report.write_text("order_id,total\nO108024,57.34\n", encoding="utf-8") print(report.exists(), report.read_text(encoding="utf-8").splitlines())
from pathlib import Path Path("archive/2023/orders.csv").write_text("order_id,total\n", encoding="utf-8")
folder.glob("*.csv") finds the files in folder whose names match the pattern: * stands for any run of characters. The order it finds them in depends on the system, so wrap it in sorted(...) whenever order matters. This function reports how many data rows (lines after the header) each daily export has.
from pathlib import Path def rows_per_file(folder): counts = {} for path in sorted(Path(folder).glob("*.csv")): lines = path.read_text(encoding="utf-8").splitlines() counts[path.name] = len(lines) - 1 return counts exports = Path("exports") exports.mkdir(exist_ok=True) (exports / "2024-01-03.csv").write_text("order_id\nO100043\n", encoding="utf-8") (exports / "2024-03-13.csv").write_text("order_id\nO101217\nO101300\n", encoding="utf-8") (exports / "notes.txt").write_text("sent to finance\n", encoding="utf-8") print(rows_per_file("exports"))
When to use it: whenever your program builds paths, checks for files, or works through a folder. Path objects can be passed to open too. Mistakes to avoid: gluing strings together and forgetting the /, assuming glob returns files in a useful order, and writing into a folder you haven't created.
Path("a") / "b.csv"builds a path;name,stemandsuffixtake it apart.mkdir(parents=True, exist_ok=True)creates folders; writing a file never creates them.glob("*.csv")finds matching files; sort the result when order matters.- Next: what text looks like on disk, as bytes, and what happens when the encoding is wrong.