Section 10 introduced the basics of pathlib. This lesson covers more of what Path can do — useful patterns for real projects.

Recap — the essentials

from pathlib import Path

p: Path = Path("data/users.csv")

p.exists()
p.is_file()
p.is_dir()
p.read_text(encoding="utf-8")
p.write_text("Hello", encoding="utf-8")
p / "subfolder" / "file.txt"        # joining
p.parent                              # containing folder
p.name                                # 'users.csv'
p.stem                                # 'users'
p.suffix                              # '.csv'

Globbing

Path.glob finds files matching a pattern in a single folder. Path.rglob searches recursively.

# all CSVs in data/
for f in Path("data").glob("*.csv"):
    print(f)

# all Python files anywhere below the current dir
for f in Path(".").rglob("*.py"):
    print(f)

Patterns:

  • * — any name within one path part
  • ** — any depth (only valid with rglob)
  • ? — any single character
  • [abc] — character class
# any 4-character name
Path(".").glob("????.txt")

# files starting with "data_"
Path(".").glob("data_*.json")

Iterating a directory

iterdir() yields every immediate child of a directory:

for child in Path("data").iterdir():
    print(child)

Combine with .is_file() or .suffix to filter:

for child in Path("data").iterdir():
    if child.is_file() and child.suffix == ".csv":
        print(child)

Renaming and moving

old: Path = Path("draft.txt")
new: Path = Path("final.txt")
old.rename(new)

rename works across folders too:

Path("draft.txt").rename(Path("archive") / "draft.txt")

The target folder must exist.

Replacing — replace

replace is like rename, but overwrites the destination if it exists:

Path("temp.txt").replace(Path("data.txt"))     # data.txt is overwritten

rename raises on Windows when the destination exists; replace handles both platforms consistently. Prefer replace when overwriting is intentional.

Creating folders

Path("logs/2026/may").mkdir(parents=True, exist_ok=True)
  • parents=True — create any missing parents
  • exist_ok=True — succeed if the folder already exists

Without exist_ok=True, mkdir raises if the folder exists.

Deleting

Path("temp.txt").unlink(missing_ok=True)     # delete file
Path("empty_dir").rmdir()                     # delete empty dir

For non-empty directories, use shutil:

import shutil
shutil.rmtree("some_folder")

File metadata — stat

p: Path = Path("data.csv")
info = p.stat()

print(info.st_size)           # size in bytes
print(info.st_mtime)          # modified time (seconds since epoch)
print(info.st_atime)          # last access time
print(info.st_ctime)          # creation/change time

For a human-readable modified time:

from datetime import datetime

modified = datetime.fromtimestamp(p.stat().st_mtime)
print(modified)

Path comparisons

Two paths are equal if their string representations match:

Path("a/b") == Path("a/b")          # True
Path("a/b") == Path("a/b/c").parent  # True

For “is this path inside that path?”, use is_relative_to (Python 3.9+):

Path("/home/me/code/file.py").is_relative_to("/home/me")    # True

Cross-platform paths

pathlib chooses the right path style based on the OS — PosixPath on macOS and Linux, WindowsPath on Windows. You write the same Python code; pathlib handles the difference.

If you need to construct Windows-style paths on a non-Windows machine (rare), use PureWindowsPath:

from pathlib import PureWindowsPath

win_path = PureWindowsPath("C:/Users/You/file.txt")
print(win_path)        # 'C:\\Users\\You\\file.txt'

PurePath types don’t touch the actual filesystem — they’re useful for path manipulation when the path is for another OS.

A practical example — clean up old log files

Find every .log file older than 7 days and delete it:

from datetime import datetime, timedelta
from pathlib import Path

cutoff = datetime.now() - timedelta(days=7)

for log in Path("logs").rglob("*.log"):
    modified = datetime.fromtimestamp(log.stat().st_mtime)
    if modified < cutoff:
        print(f"Removing {log}")
        log.unlink()

Three modules together — pathlib, datetime, and the standard for loop — make this a small but real script.

What’s next

Final lesson of this section — os and sys, for talking to the operating system.

Toggle theme (T)