Skip to content
Advertisement

python Path from pathlib module doesn’t add path separator

I have the following issue using Path from the pathlib library:

from pathlib import Path
import os

path_list = ["path","to","directory1","directory2"]
join_str = os.path.sep
my_path = join_str.join(path_list)
my_path = str(Path(my_path))
dir_exists = os.path.isdir(my_path)
Output:
my_path = "path/to/directory1/directory2"
dir_exists = False

I have tried with Path itself and manually giving it a path that I know exists:

(Pdb) test2 = str(Path("Users","userK","my_directory"))
(Pdb) os.path.isdir(test2)
False
(Pdb) test2
Users/userK/my_directory

I was wondering why Path doesn’t simply add the backslash at the beginning? Is there a better way to build my path with the needed path separator from a list? I didn’t notice it before, because I use os.getcwd() and add to it to build my paths:

(Pdb) my_cwd = os.getcwd()
(Pdb) my_path = str(Path(my_cwd,"directory1"))
(Pdb) os.path.isdir(my_path)
True 

However, I am not in the position code-wise to explicitly build the path I need, hence the issue.

Thanks!

Advertisement

Answer

Path cannot assume how the result will be used further, so it constructs the path object from the input data as is.

I will demonstrate with examples.

To begin with, prepare the directories in /tmp:

zyzop@localhost:~$ cd /tmp/
zyzop@localhost:/tmp$ pwd
/tmp
zyzop@localhost:/tmp$ mkdir -p path/to/directory1/directory2
zyzop@localhost:/tmp$ ls -ld path/to/directory1/directory2
drwxr-xr-x 2 zyzop zyzop 4096 Jul  8 03:28 path/to/directory1/directory2
zyzop@localhost:/tmp$ python3

Let’s create a relative path from the list of its parts

>>> from pathlib import Path
>>> path_list = ["path", "to", "directory1", "directory2"]
>>> my_path = Path(*path_list)
>>> my_path
PosixPath('path/to/directory1/directory2')

Since the relative path exists in the current directory, we can check its existence

>>> my_path.exists()
True
>>> my_path.is_absolute()
False
>>> my_path.resolve()
PosixPath('/tmp/path/to/directory1/directory2')

There are two ways to create an absolute path. The first is to attach the path to the current directory to the beginning of the path

>>> my_path1 = Path(Path().cwd(), *path_list)
>>> my_path1
PosixPath('/tmp/path/to/directory1/directory2')
>>> my_path1.is_absolute()
True
>>> my_path1.exists()
True

The second way is to explicitly specify the path from the root

>>> path_list2 = ["/", "tmp", "path", "to", "directory1", "directory2"]
>>> my_path2 = Path(*path_list2)
>>> my_path2
PosixPath('/tmp/path/to/directory1/directory2')
>>> my_path2.exists()
True
>>> my_path2.is_absolute()
True

For example, let’s see what happens to relative paths in another directory. Let’s move to the home directory

>>> import os
>>> os.chdir(Path.home())
>>> Path().cwd()
PosixPath('/home/zyzop')

Let’s check the existence of paths

>>> my_path
PosixPath('path/to/directory1/directory2')
>>> my_path.exists()
False
>>> my_path2
PosixPath('/tmp/path/to/directory1/directory2')
>>> my_path2.exists()
True

Now let’s see how the absolute paths have changed. Since my_path is a relative path, it will always resolve relative to the current directory

>>> my_path.resolve()
PosixPath('/home/zyzop/path/to/directory1/directory2')

my_path 2 is an absolute path, so it will always be unchanged

>>> my_path2.resolve()
PosixPath('/tmp/path/to/directory1/directory2')

More details can be found here: https://docs.python.org/3/library/pathlib.html

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement