Warm tip: This article is reproduced from stackoverflow.com, please click
python windows path relative-path absolute-path

Convert Windows relative path to POSIX relative path so I can join POSIX absolute path and Windows r

发布于 2020-03-27 10:32:12

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.

Questioner
finefoot
Viewed
211
finefoot 2019-07-04 02:21

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:

def example(abspath, relpath):
    import pathlib
    abspath = pathlib.PurePosixPath(abspath)
    relpath = pathlib.PurePath(relpath)
    return str(abspath.joinpath(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 a PurePosixPath or a PureWindowsPath)

An example call on Linux might look like:

>>> example("/x/y/z", "a/b/c")
'/x/y/z/a/b/c'

An example call on Windows might look like:

>>> example("/x/y/z", "a\\b\\c")
'/x/y/z/a/b/c'

So it produces the correct POSIX path on both platforms.