Python pathlib: Modern File Path Handling
Imagine navigating to a friend's house. You could follow vague paper directions like "turn left at the big tree, then right at the red mailbox." Or you could use GPS, which understands addresses, calculates routes, and handles all the tricky details for you.
Python's pathlib module is like GPS for file paths. The old way (os.path) treats paths as plain strings and requires you to manually juggle slashes, extensions, and platform differences. pathlib gives you smart Path objects that understand what paths are and how they work.
In this tutorial, you'll learn how to create, inspect, join, and search paths using pathlib. Since we're running in the browser, we'll focus on the path manipulation features that work without a real filesystem.
How Do You Create a Path Object?
Import PurePosixPath from pathlib and pass it a string. A PurePosixPath is a path object that works with Unix-style forward slashes and doesn't need a real filesystem.
On your own computer, you'd normally use Path (which detects your operating system). Here we use PurePosixPath because it works everywhere, including in the browser. The methods and properties are the same.
What Can You Learn from a Path Object?
Path objects have useful properties that let you extract parts of a file path without any string splitting or slicing.
Let's break down what each property gives you:
main.pymain.py/home/alice/projects/appWalking up the directory tree
You can chain .parent to go up multiple levels, or use the .parents property to get all ancestor directories.
How Do You Join Paths Together?
One of the best features of pathlib is the / operator for joining paths. Instead of worrying about slashes, you just use / between Path objects or strings.
The / operator automatically handles the separator for you. No more worrying about whether to add a slash or not.
import os
path = os.path.join('/home', 'alice', 'docs')
# String manipulation, easy to mess upfrom pathlib import PurePosixPath
path = PurePosixPath('/home') / 'alice' / 'docs'
# Clean, readable, type-safeChanging file names and extensions
Path objects have methods to swap out the file name or extension, which is handy for creating related files.
How Do You Search for Files with Glob Patterns?
On a real filesystem, Path objects can search for files using glob patterns — simple wildcard expressions. The * matches any sequence of characters, and ** matches any number of directories.
Since we can't access a real filesystem here, let's learn the patterns and practice with PurePosixPath.match(), which checks if a path matches a glob pattern.
Common glob patterns you'll use:
*.py — All Python files*.txt — All text filestest_* — Files starting with test_**/*.py — All Python files in any subdirectorydata/* — Everything directly inside the data folderWhy Choose pathlib Over os.path?
Before pathlib (added in Python 3.4), everyone used os.path for file path manipulation. Both work, but pathlib is generally better for new code.
import os
path = '/home/alice/report.txt'
print(os.path.basename(path)) # report.txt
print(os.path.dirname(path)) # /home/alice
print(os.path.splitext(path)[1]) # .txt
new = os.path.join('/home', 'bob', 'file.txt')from pathlib import PurePosixPath
path = PurePosixPath('/home/alice/report.txt')
print(path.name) # report.txt
print(path.parent) # /home/alice
print(path.suffix) # .txt
new = PurePosixPath('/home') / 'bob' / 'file.txt'Key advantages of pathlib:
.name and .parent are clearer than os.path.basename() and os.path.dirname().path.parent / 'sibling.txt'./ vs \ on different operating systems.What Is a Common pathlib Pattern?
Here's a practical pattern: organizing files by their extension. This shows how pathlib makes file organization logic clean and readable.
Practice Exercises
Given the path /home/user/documents/essay.txt, create a PurePosixPath and print the file name, the suffix (extension), and the parent directory, each on its own line.
Expected output:
essay.txt
.txt
/home/user/documentsWhat does this code print? Think about how the / operator joins paths.
from pathlib import PurePosixPath
base = PurePosixPath('/home/alice')
result = base / 'projects' / 'app' / 'main.py'
print(result)Given the path /data/report.csv, use pathlib to create a new path with the extension changed to .json. Print both the original and new path.
Expected output:
Original: /data/report.csv
Converted: /data/report.jsonThis code tries to build a path by concatenating strings, but it produces an incorrect result. Fix it to use pathlib's / operator.
Expected output:
/home/user/docs/notes.txtGiven a list of file paths, use pathlib to filter only the .py files and print their stem (filename without extension), one per line, in alphabetical order.
File list: ['app/main.py', 'app/utils.py', 'app/data.csv', 'app/config.json', 'app/test_app.py']
Expected output:
main
test_app
utils