91

When I need to define a file system path in my script, I use os.path.join to guarantee that the path will be consistent on different file systems:

from os import path
path_1 = path.join("/home", "test", "test.txt")

I also know that there is the pathlib module that basically does the same:

from pathlib import Path
path_2 = Path("/home") / "test" / "test.txt"

What is the difference between these two ways to handle paths? Which one is better?

4
  • 7
    Basically you can do it either way, it really doesn’t matter much. It probably boils down to what syntax you prefer. Personally I don’t like the slash being “abused” as a path concatenation operator, therefore I prefer os.path.join, but it’s really just a matter of taste. Commented Apr 15, 2021 at 16:43
  • 1
    As far as functionality goes, both do the same thing. It's mostly a matter of preference which one you like. treyhunner.com/2018/12/why-you-should-be-using-pathlib Commented Apr 15, 2021 at 16:46
  • 16
    You can do the same as path_2 = Path("home", "test", "test.txt") and forget about the slash Commented Jun 22, 2021 at 5:54
  • 1
    In some cases you can decided based on if you are already using os.path or pathlib. If you've imported and are using one of them already then presumably just keep using that one to avoid additional imports and inconsistency. Commented Jun 1, 2024 at 4:42

3 Answers 3

109

pathlib is the more modern way since Python 3.4. The documentation for pathlib says that "For low-level path manipulation on strings, you can also use the os.path module."

It doesn't make much difference for joining paths, but other path commands are more convenient with pathlib compared to os.path. For example, to get the "stem" (filename without extension):

os.path: splitext(basename(path))[0]

pathlib: path.stem

Also, you can use the same type of syntax (commas instead of slashes) to join paths with pathlib as well:

path_2 = Path("/home", "test", "test.txt")

Sign up to request clarification or add additional context in comments.

3 Comments

One issue with pathlib.path is when working with bucket gc:// or s3:// pathlib causes the prefix to be reduce to gc:/ etc. so better to work with os.join
@skibee In this case you can also use cloudpathlib
@skibee os.path is not meant for URIs. As the name implies, it's for operating system specific paths (file paths). On windows for example it uses backslashes.
1

Beware that there are some differences1 in how those modules handle paths and that may force you to choose one over the other, depending on the application.
Indeed the documentation says1:

pathlib’s path normalization may render it unsuitable for some applications

One of those differences, which is particularly relevant for this question, is the automatic normalization of paths done by pathlib's Path:

import os
import pathlib

print(os.path.join(".", "program"))
print(pathlib.Path(".") / "program")

Output:

./program
program

1: https://docs.python.org/3/library/pathlib.html#comparison-to-the-os-and-os-path-modules

Comments

1

os.path is string-based while pathlib is object oriented

os.path operates on strings while pathilib is object oriented. So if "/home/test/test.txt" is the absolute path (in POSIX format) to access to the file test.txt in the directory /home/test/, the instructions:

from os import path
path_1 = path.join("/home", "test", "test.txt")

(executed in a Linux system) return in path_1, the string "/home/test/test.txt" (link to os.path.join() documentation.)

On the other hand the following instructions:

from pathlib import Path
path_2 = Path("/home") / "test" / "test.txt"

return an object called path_2 which represents the file.

A function and a method available with the 2 approaches

By previous initialization, essentially:

  • the string path_1 can be used as argument of other functions of the module os.path, for example:
from os import path
if path.exists(path_1):
    # the file exists
  • the object path_2 is an instance of the class pathlib.Path so with this object it is possible to call all methods of the class Path; furthermore if path_2 is created on a POSIX compliant system (as Linux) its type is PosixPath (a subclass of Path) else if path_2 is created on a Windows system its type is WindowsPath (a subclass of the class Path); an example of method available on the object path_2 is exists(), and the snippet of code below shows its used:
from pathlib import Path
path_2 = Path("/home") / "test" / "test.txt"
if path_2.exists():
    # the file exists

Link

See this link to know other differences between this two ways to manage path with Python.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.