Renaming outputs, grouping files by extension and finding sibling files are everyday tasks.
A path exposes its components as properties, all computed from the string without touching the disk:
p.namefinal component:report.tar.gzp.suffixlast extension:.gz;p.suffixes:['.tar', '.gz']p.stemname without the last suffix:report.tarp.parentthe containing path;p.parentsall ancestors, indexable (p.parents[1])p.partsa tuple of components;p.anchorthe drive and root (/orC:\)
To derive related paths, use the with_* methods, which return new paths:
p.with_suffix(".json")replaces the last suffix (pass""to remove it)p.with_name("other.txt")replaces the final componentp.with_stem("report-v2")keeps the suffix and changes the stem
Typical pattern: write out = src.with_suffix(".processed.csv") or put outputs next to inputs with src.parent / f"{src.stem}.out".
Gotchas: suffix only sees the last dot, so .tar.gz needs suffixes; a leading dot file like .bashrc has no suffix (its stem is .bashrc). The parent of a relative single name is Path("."), and the parent of / is / itself.
Example
from pathlib import Path
p = Path("/srv/backups/db.2025-03-01.tar.gz")
print(p.name) # db.2025-03-01.tar.gz
print(p.stem) # db.2025-03-01.tar
print(p.suffix) # .gz
print(p.suffixes) # ['.2025-03-01', '.tar', '.gz']
print(p.parent) # /srv/backups
print(p.parents[1]) # /srv
print(p.parts[:3]) # ('/', 'srv', 'backups')
src = Path("photos/cat.jpeg")
print(src.with_suffix(".png")) # photos/cat.png
print(src.with_stem("cat_small")) # photos/cat_small.jpeg
print(Path(".bashrc").suffix == "") # True
print(Path("notes.txt").parent) # .Remember
name,stem,suffix,parentandpartsare pure string operationswith_suffix,with_nameandwith_stemderive new paths- Dots in names are tricky: use
suffixesfor multi-part extensions
Watch out for
- Expecting
suffixto return '.tar.gz'; it only returns the last extension.