Paths with pathlib and Missing Files
18 min · Beginner
Need help? Ask a tutor on WhatsApp (opens in a new tab)A file name like reports/marks.txt is a path. Writing paths as plain text breaks when Windows and macOS use different separators. The pathlib module gives you a Path object that works on every system.
Path objects
Path is an object from pathlib that stands for a file or folder location. You join parts with / and ask it for its name, suffix, parent, or whether it exists.
Joining strings with "/" or "\\" is fragile. A Path joins parts with the / operator and picks the right separator for your computer. It also knows the pieces of a name.
from pathlib import Path
p = Path("reports") / "marks.txt"print(p.name)print(p.stem)print(p.suffix)print(p.parent.name)print(p.as_posix())Example 1 · Take a path apart
from pathlib import Path
report = Path("exports") / "2026" / "orders.csv"print(report.name)print(report.stem)print(report.suffix)print(report.parent.as_posix())orders.csv orders .csv exports/2026
What this code does
- Each attribute gives one piece of the path.
as_posix()shows forward slashes on every system.
name is the last part, stem is the name without the extension, and suffix is the extension. parent is the folder that holds it. as_posix() always prints with forward slashes, so the output is the same on every computer.
Folders, quick read and write
Small text files do not need a with block. write_text and read_text open, use and close the file in one call. mkdir makes a folder, and glob finds files by pattern.
from pathlib import Path
folder = Path("exports")folder.mkdir(exist_ok=True)file = folder / "orders.txt"file.write_text("A101\nA102\n", encoding="utf-8")
print(file.exists())print(file.read_text(encoding="utf-8").splitlines())print(sorted(p.name for p in folder.glob("*.txt")))Example 2 · Write a file in a new folder
from pathlib import Path
folder = Path("backup")folder.mkdir(exist_ok=True)(folder / "ids.txt").write_text("7\n8\n9\n")print(len((folder / "ids.txt").read_text().splitlines()))print([p.name for p in folder.iterdir()])3 ['ids.txt']
What this code does
mkdircreates the folder, andwrite_textcreates the file inside it.iterdir()lists everything in the folder.
exist_ok=True stops mkdir from failing when the folder is already there. exists() answers True or False. glob("*.txt") yields every matching file, and sorted fixes the order, because the order from the disk is not promised.
Handling a missing file
FileNotFoundError is the error Python raises when you open or read a file that does not exist. Catch it with try and except to give a friendly message or a default.
Opening a file that is not there raises FileNotFoundError. A crash is rude to the user. Catch the error and decide what to do, such as using an empty result.
def load_lines(name): try: with open(name, encoding="utf-8") as f: return f.read().splitlines() except FileNotFoundError: return []
print(load_lines("absent.txt"))Example 3 · A missing file gives a default
def load_marks(name): try: with open(name) as f: return [int(x) for x in f.read().split()] except FileNotFoundError: return []
print(load_marks("marks.txt"))with open("marks.txt", "w") as f: f.write("72 85 90")print(load_marks("marks.txt"))[] [72, 85, 90]
What this code does
- The first call finds no file, so the function returns an empty list.
- After the file is written, the same call returns the marks.
The function returns an empty list when the file is missing. Other errors, such as a wrong type, are not hidden, because only FileNotFoundError is caught.
Check first or just try
You can ask exists() before opening, or you can try and catch the error. Python programmers prefer to try, because the file can disappear between the check and the open.
from pathlib import Path
name = "settings.txt"if Path(name).exists(): print("found")else: print("creating") Path(name).write_text("theme=dark\n")
try: print(Path(name).read_text().strip())except FileNotFoundError: print("still missing")Example 4 · Count files by suffix
from pathlib import Path
folder = Path("mixed")folder.mkdir(exist_ok=True)for name in ["a.txt", "b.txt", "c.csv"]: (folder / name).write_text("x")txt = sorted(p.name for p in folder.glob("*.txt"))csv_files = sorted(p.name for p in folder.glob("*.csv"))print(txt)print(csv_files)['a.txt', 'b.txt'] ['c.csv']
What this code does
- The pattern
*.txtmatches any name that ends in.txt. - The folder
mixedholds only these three files.
The first part checks, then creates the file when it is missing. The try part reads the file and only prints "still missing" if something removed it in between.
Next step
Check your understanding
10 quick questions