Videos
I've written a hybrid "why pathlib" and "pathlib cheat sheet" post: Python's pathlib module.
I see this resource as a living document, so feedback is very welcome.
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")
os.path is string-based while pathlib is object oriented
os.path operates on strings while pathlib 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 commands:
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 commands:
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 the previous initialization, essentially:
The string
path_1can be used as argument of other functions of the moduleos.path. For example, to check if a file exists:from os import path if path.exists(path_1): # the file exists do stuffThe object
path_2is an instance of the classpathlib.Path, so with this object it is possible to call all methods of the classPath.Furthermore, if
path_2is created on a POSIX compliant system (such as Linux), its type isPosixPath(a subclass ofPath), else ifpath_2is created on a Windows system, its type isWindowsPath(a subclass of the classPath).An example of the methods available on the object
path_2is theexists()method. The snippet of code below shows how it is used:from pathlib import Path if path_2.exists(): # the file exists do stuff
Link
See this article to learn about other differences between the two ways of managing paths with Python: Paths in Python: Comparing os.path and pathlib modules
Use resolve()
Simply use Path.resolve() like this:
p = p.resolve()
This makes your path absolute and replaces all relative parts with absolute parts, and all symbolic links with physical paths. On case-insensitive file systems, it will also canonicalize the case (file.TXT becomes file.txt).
Avoid absolute() before Python 3.11
The alternative method absolute() was not documented or tested before Python 3.11 (See the discussion in the bug report created by @Jim Fasarakis Hilliard).
Fixes were merged in January 2022.
The difference
The difference between resolve and absolute is that absolute() does not replace the symbolically linked (symlink) parts of the path, and it never raises FileNotFoundError. It does not modify the case either.
If you want to avoid resolve() (e.g. you want to retain symlinks, casing, or relative parts) then use this instead on Python <3.11:
p = Path.cwd() / "file.txt"
This works even if the path you are supplying is absolute -- in that case the cwd (current working directory) is ignored.
Beware non-existing file on Windows
If the file does not exist, in Python 3.6 to 3.9 on Windows, resolve() does not prepend the current working directory. See issue 38671, fixed in Python 3.10.
Beware FileNotFoundError
On Python versions predating v3.6, resolve() does raise a FileNotFoundError if the path is not present on disk.
So if there's any risk to that, either check beforehand with p.exists() or try/catch the error.
# check beforehand
if p.exists():
p = p.resolve()
# or except afterward
try:
p = p.resolve()
except FileNotFoundError:
# deal with the missing file here
pass
If you're dealing with a path that's not on disk, to begin with, and you're not on Python 3.6+, it's best to revert to os.path.abspath(str(p)).
From 3.6 on, resolve() only raises FileNotFoundError if you use the strict argument.
# might raise FileNotFoundError
p = p.resolve(strict=True)
But beware, using strict makes your code incompatible with Python versions predating 3.6 since those don't accept the strict argument.
You're looking for the method .absolute, if my understanding is correct, whose documentation states:
>>> print(p.absolute.__doc__)
Return an absolute version of this path. This function works
even if the path doesn't point to anything.
No normalization is done, i.e. all '.' and '..' will be kept along.
Use resolve() to get the canonical path to a file.
With a test file on my system this returns:
>>> p = pathlib.Path('testfile')
>>> p.absolute()
PosixPath('/home/jim/testfile')
This method seems to be a new, and still, undocumented addition to Path and Path inheritting objects.
Created an issue to document this.
ยป pip install pathlib