Why Doesn't Os.Path.Join() Work in This Case

Why doesn't os.path.join() work in this case?

The latter strings shouldn't start with a slash. If they start with a slash, then they're considered an "absolute path" and everything before them is discarded.

Quoting the Python docs for os.path.join:

If a component is an absolute path, all previous components are thrown away and joining continues from the absolute path component.

Note on Windows, the behaviour in relation to drive letters, which seems to have changed compared to earlier Python versions:

On Windows, the drive letter is not reset when an absolute path component (e.g., r'\foo') is encountered. If a component contains a drive letter, all previous components are thrown away and the drive letter is reset. Note that since there is a current directory for each drive, os.path.join("c:", "foo") represents a path relative to the current directory on drive C: (c:foo), not c:\foo.

Python3 - os.path.join doesn't join the paths

From the documentation of os.path.join:

[...] If a component is an absolute path, all previous components are thrown away and joining continues from the absolute path component.

So most likely path starts with a slash, i.e. path = "/subfolder" and hence the previous base_dir is discarded.

os.path.join not join directory and file

If the filenames in array are absolute paths, this will not work. join will restart the filename from an absolute path. For example, on Windows join('C:/x', 'C:/y') results in 'C:/y'. On Linux, join('/x', '/y') returns '/y'.

In your loop file[:-len(srcSfx)] + destSfx is an absolute path, so the intended prefix, save_dir is simply discarded. To avoid that, call to basename similarly to how you used dirname when constructing save_dir:

p = os.path.join(save_dir, os.path.basename(file)[:-len(srcSfx)] + destSfx)

As a minor aside, I generally prefer to import the names like

from os.path import basename, dirname, join

In that case, the result is a bit shorter and easier to read:

save_dir = join(dirname(array[0]), "Converted_files")
...
join(save_dir, basename(file)[:-len(srcSfx)] + destSfx)

Why are os.path.join() on a list and os.path.sep.join() on a list not functionally identical?

os.path.join is not intended to be the inverse of path.split(os.path.sep). If you read the docs, you'll find a description of a much more complicated process than just sticking os.path.sep between the arguments. The most relevant part is the following:

On Windows... Note that since there is a current directory for each drive, os.path.join("c:", "foo") represents a path relative to the current directory on drive C: (c:foo), not c:\foo.

You should probably be using pathlib.PurePath(path).parts rather than path.split(os.path.sep).

os.path.join seems sensitive to opening slash, why?

From the join() docstring:

If a component is an absolute path, all previous components are thrown away and joining continues from the absolute path component.

'/Documents/Jeopardy/output' is an absolute path, so the first part is discarded.

Behaviorally, using the relative rather than absolute path arguably makes more sense; it doesn't make a ton of sense to prepend anything to an absolute path, since it already starts at the FS root.

os.path.join() on windows?

os.path.join(folder1 + "\\" + folder2)

MAC and Linux work with singe /

but in Windows we have to pass \\

Try these it will work

Python os.path.join on Windows

Windows has a concept of current directory for each drive. Because of that, "c:sourcedir" means "sourcedir" inside the current C: directory, and you'll need to specify an absolute directory.

Any of these should work and give the same result, but I don't have a Windows VM fired up at the moment to double check:

"c:/sourcedir"
os.path.join("/", "c:", "sourcedir")
os.path.join("c:/", "sourcedir")


Related Topics



Leave a reply



Submit