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