Reputation: 11232
I'm looking for a platform-independent solution. Everything works on Linux because os.walk
already returns POSIX paths. However, if I'm on Windows I might get the following two paths:
abspath = "/x/y/z" # given path for a remote server which uses POSIX paths
relpath = "a\\b\\c" # acquired from local file system via os.walk, so it uses slash or backslash depending on the platform
The desired result of the joined path for this example would be:
'/x/y/z/a/b/c'
However, naturally, using posixpath.join
results in:
>>> posixpath.join(abspath, relpath)
'/x/y/z/a\\b\\c'
So when I'm on Windows and have a relative path like a\\b\\c
, I think it might make sense to convert it to a POSIX relative path a/b/c
first, so I am able to use posixpath.join
afterwards?
However, I don't believe simply replacing every backslash with a slash is best practice - or is it? I couldn't find any function which provides such a conversion.
Upvotes: 3
Views: 2810
Reputation: 11232
Instead of using os
which depends on the platform, or posixpath
which will only work with POSIX paths, Python's pathlib
module seems to be a good choice here:
This module offers classes representing filesystem paths with semantics appropriate for different operating systems
Here is a solution for the example from the question above:
import pathlib
def example(abspath, relpath):
abspath = pathlib.PurePosixPath(abspath)
relpath = pathlib.PurePath(relpath)
return str(abspath / relpath)
pathlib.PurePosixPath
is being used for abspath
because the final path is supposed to be a POSIX path and pathlib.PurePath
works on both Windows and Linux:
pathlib.PurePath
- A generic class that represents the system’s path flavour (instantiating it creates either aPurePosixPath
or aPureWindowsPath
)
An example call on Linux might look like:
>>> import platform
>>> platform.system()
'Linux'
>>> example("/x/y/z", "a/b/c")
'/x/y/z/a/b/c'
An example call on Windows might look like:
>>> import platform
>>> platform.system()
'Windows'
>>> example("/x/y/z", "a\\b\\c")
'/x/y/z/a/b/c'
So it produces the correct POSIX path on both platforms.
Upvotes: 2
Reputation: 11091
Try using pathlib.Path
, it handles the tricky parts of manipulating paths across platforms.
https://docs.python.org/3/library/pathlib.html
from pathlib import Path, PosixPath
if __name__ == '__main__':
BASE_DIR = Path('/path/to/base')
rel_path = r'path\to\rel'
print(BASE_DIR)
print(rel_path)
print(BASE_DIR / rel_path)
output:
\path\to\base
path\to\rel
\path\to\base\path\to\rel
Upvotes: 3