Getting Started with pathlib — Object-Oriented Path Handling

When working with Python, dealing with file paths or directories is quite common. Whether it's saving logs, reading and writing configuration files, or organizing data files, these are everyday tasks. In the past, we used to handle these tasks by mixing modules like os.path, glob, and shutil, but now that's no longer necessary. Why, you ask?

Because we have pathlib.

What is pathlib?

pathlib is an object-oriented module designed for path manipulation that has been available since Python 3.4. While previous methods treated file paths as simple strings, pathlib treats a "path" as an object itself. As a result, tasks like joining paths, checking their existence, or reading and writing files have become much more clear and readable.

from pathlib import Path

▶ This Path class automatically works as PosixPath (macOS/Linux) or WindowsPath based on your operating system. This means you don't have to worry about which OS you're using!


Essential Features and Examples of pathlib

1. Creating a Path Object

p = Path('data/example.txt')
print(p.resolve())  # Returns absolute path

Although it looks like a string, this is an object. You can manipulate paths flexibly through various methods and attributes.

2. Path Concatenation: Using the / Operator

data_dir = Path('data')
file_path = data_dir / 'sample.txt'

Using the slash operator / to join paths is very Pythonic. It offers better readability and stability compared to string concatenation.

3. Extracting Path Information

It's also very convenient to separate path components, such as parent directory, name, and extension.

p = Path('data/sample.txt')
print(p.parent)   # data
print(p.name)     # sample.txt
print(p.stem)     # sample
print(p.suffix)   # .txt

4. Checking Existence

Returns the result as a boolean.

p.exists()     # Existence check
p.is_file()    # Is it a file?
p.is_dir()     # Is it a directory?

5. Creating Directories

p = Path('logs/2025/05')
p.mkdir(parents=True, exist_ok=True)

You can create nested directories all at once, and it won't throw an error if they already exist.

6. Reading and Writing Files

p = Path('output.txt')
p.write_text("Hello, World!")

text = p.read_text()
print(text)

You can also handle binary files:

p.write_bytes(b'binary data')
data = p.read_bytes()

7. Searching Files/Directories

print(list(Path('.').glob('*.py')))      # List of .py files in the current folder
print(list(Path('.').rglob('*.py')))     # Recursively search in subfolders

glob() returns a generator, so it’s good to convert it to a list for checking.

8. Deleting, Moving, Renaming Files

p.unlink()           # Delete
p.rename('newname')  # Rename (within the same directory)
p.replace('newpath') # Move and overwrite

rename() may fail if the target path exists, so use replace() if you need to overwrite. For copying, use shutil.copy().


Comparison: os.path vs pathlib

# os.path
import os
os.path.exists('foo/bar.txt')

# pathlib
Path('foo/bar.txt').exists()
  • The code is much more readable and maintainable.
  • Particularly familiar syntax structure for commands like cd, ls, mkdir commonly used in Linux environments.

Why Should We Use pathlib?

  • It provides structured code using Path objects instead of strings.
  • OS-independent path handling (Windows vs POSIX)
  • Integrates functionalities of os.path, glob, and shutil
  • Enhances maintainability in test code, logging, error handling, etc.

Tux assembling file path blocks in a Python T-shirt

In Conclusion

Just as Counter and defaultdict have made handling collections more elegant, pathlib is revolutionizing the way we manage file paths. The old days of struggling with string manipulation are now behind us. Try executing the examples illustrated in this article one by one. You'll find that it becomes second nature much quicker than you think.

In the next part, we'll cover advanced techniques for automating file copying/backing up using shutil. Stay tuned!

If you’re curious about the previous posts, you can check them by clicking the links below:

Mastering Python Standard Library 1 - collections.Counter

Mastering Python Standard Library 2 - collections.defaultdict