pathlib — a Better Way to Work with Paths in Python

DZ
3 min readJul 19, 2023

--

Photo by Hermann from Pixabay

Traditionally programmers in Python handle file and directory paths as strings, eighter writing the string directly or using modules like os . That can be ugly and sometimes can lead to bugs.

A better way to handle paths is by using pathlib module which is part of the Python standard library, so if you have Python installed, you are good to go.

With pathlib , instead of using strings, we use Path object:

from pathlib import Path
path_to_my_file = Path('/home/my_user/my_file.txt')

# PosixPath('/home/my_user/my_file.txt')

The Path class also has some useful methods that help you start with your path like Path.home() that returns Path object with the path to the home directory of the user, and Path.cwd() that returns the path to the current working directory.

If you look closely at the previous example, you see that we didn’t get a Path object, but PosixPath . The Path class let us keep our code platform-independent, meaning it will work on both Windows and Unix-based platforms. In a Unix-based platform such as Ubuntu and MacOS the Path class returns a PosixPath object, while on Windows it returns WindowsPath . You don’t need to worry about it, the Path class handles the differences between the platforms for you.

Joining paths is much more simple and intuitive than with os.path.join , using only the / operator to join paths

path_to_my_file = Path.home() / 'my_file.txt'

# PosixPath('/home/my_user/my_file.txt')

An absolute path can be generated by

Path('.').absolute()

# PosixPath('/home/my_user)

You can always convert Path object back to a string using casting

str(path_to_my_file)

# '/home/my_user/my_file.txt'

Extract Components of a Path

The Path object can also help us to get different components of the full path.

Get the file name (without extension):

path_to_my_file.stem

# 'my_file'

Get the file name (with extension):

path_to_my_file.name

# 'my_file.txt'

Get only the extension:

path_to_my_file.suffix

# '.txt'

Get the parent directory as another Path object:

path_to_file.parent

# PosixPath('/home/my_user)

Get the base path (before the directories):

path_to_file.anchor

# '/' on linux
# 'C:\\' on Windows

Get all parts as a tuple:

path_to_file.parts

# ('/', 'home', 'my_user', 'my_file.txt')

Create, Remove, and Change Files and Directories

A file can be removed by:

path_to_my_file.unlink(missing_ok=True)

if the missing_ok flag is set to True an error will not be raised if the file doesn’t exist.

We can now check if the file exists (that also works for directories):

path_to_my_file.exists()

# False

Other methods we can use to check files and directories are:

 path_to_my_file.is_file()

# False

path_to_my_file.is_dir()

# False

path_to_my_file.parent.is_dir()

# True

Now let’s recreate the file and write text to it

path_to_my_file.touch(exist_ok=True)
path_to_my_file.write_text('Hello')

if the exist_ok flag is set to True an error will not be raised if the file exists.

To read the content

print(path_to_my_file.read_text())

# Hello

To rename a file, we need to create a new path with the new name. We can use the with_stem method to replace the name of the file (without the extension) and then rename the file

new_name_path = path_to_my_file.with_stem('new_file')
path_to_my_file.rename(new_name_path)

We can also change the extension

new_suffix = new_name_path.with_suffix('.md')
new_name_path.replace(new_suffix)

Creating a directory can be done using mkdir

new_dir_path = path_to_my_file.parent / 'new_dir'
new_dir_path.mkdir(parents=True, exist_ok=True)

where the parents flag, if set to True will also create the intermediate directories.

To remove the last child directory

new_dir_path.rmdir()

List Files by Pattern

Finally, we can use the glob method to search for files by pattern inside a directory

current_dir = Path.cwd()
txt_files = current_dir.glob('*.txt')

or, for a recursive search inside subdirectories

txt_files = current_dir.rglob('*.txt')

Final Thoughts

The pathlib module is a powerful tool to handle paths, files, and directories. In this article, I showed just a little bit of the Path class and I hope you’ll explore it more, and move from using the old os module.

--

--