6

As we know, windows accept both "\" and "/" as separator. But in python, "\" is used. For example, call os.path.join("foo","bar"), 'foo\\bar' will be returned. What's annoying is that there's an escape character, so you cannot just copy the path string and paste to your explorer location bar.

I wonder is there any way to make python use "/" as default separator, I've tried change the value of os.path.sep and os.sep to "/", but os.path.join still use "\\".

what's the right way?

PS:

I just don't understand why python is using "\" as default separator on windows, maybe old version of windows don't support "/"?

ThemeZ
  • 473
  • 1
  • 5
  • 15
  • 3
    os.path.sep should be used for joining *filenames* and *directory* names...who said that os.path.sep has to be used for URLs???? –  Aug 23 '12 at 06:55
  • 1
    Why using `os.path.join` if you don't care about the correct path seperator in the end? – sloth Aug 23 '12 at 06:55
  • Well you could create your own function which uses '/' if on Windows or uses `os.path.join` on other platforms. Or you could replace '\\' with '/' (or '\') in the path before you display it. – cdarke Aug 23 '12 at 06:55
  • @BigYellowCactus Because my program may run on other system, but I just want to change the separator on windows. – ThemeZ Aug 23 '12 at 06:59
  • @ThemeZ Are there systems other than windows that uses backslashes as path seperator? – sloth Aug 23 '12 at 07:02
  • @cdarke That's a resolution, but I think it may be more elegant if I can choose my own separator for specific system? – ThemeZ Aug 23 '12 at 07:06
  • @BigYellowCactus I'm not sure, could you tell all systems that run python and their separator? – ThemeZ Aug 23 '12 at 07:07
  • @ThemeZ I think the only other system that uses backslash is Symbian OS. Btw, I don't see a problem at all, since you can just call `print`, and the extra backslash is gone. See my answer – sloth Aug 23 '12 at 07:20
  • "\" was what Windows used originally, (even if the knew, or should knew, that "\" is escape character in Unix and will cause problems in integration later. So Python does the Right Thing (tm). Only later MSFTies decided to join rest of the world and allow for "/". So now they do have TWO standard separators. The more standards the merrier. – Peter M. - stands for Monica Oct 28 '15 at 19:57

5 Answers5

13

To answer your question as simply as possible, just use posixpath instead of os.path.

So instead of:

from os.path import join
join('foo', 'bar')
# will give you either 'foo/bar' or 'foo\\bar' depending on your OS

Use:

from posixpath import join
join('foo', 'bar')
# will always give you 'foo/bar'
semicolon
  • 2,530
  • 27
  • 37
7

It is all about how Python detects your os:

# in os.py
if 'posix' in _names:
    ...
    import posixpath as path   

elif 'nt' in _names:
    ...
    import ntpath as path

So, on Windows the ntpath module is loaded. If you check the ntpath.py and posixpath.py modules you'd notice that ntpath.join() is a bit more complex and that is also because of the reason you've mentioned: Windows understands / as a path separator.

Bottomline: although you can use posixpath.join() in Windows (as long as the arguments are in POSIX format), I would not recommend doing it.

Zaur Nasibov
  • 22,280
  • 12
  • 56
  • 83
2

Why not define a custom display function?

e.g.

def display_path(path):
    return path.replace("\\", "/")

And if you want to substitute str.join for os.path.join, you can just do this (str.join expects a single list, os.path.join expects *args):

join = lambda *args: "/".join(args)

Perhaps better would be to let Python normalize everything, then replace, e.g.:

join = lambda *args: os.path.join(*args).replace("\\", "/")

The only issue with the above might be on posix when there is a space in the file path.

You could then put an if statement at the top of your utils file and define display_path and join as a no-op and as os.path.join respectively if not on Windows.

Jeff Tratner
  • 16,270
  • 4
  • 47
  • 67
1

I would not recommend doing this.

Note that while windows does accept slash / as path seperator also, it has a different meaning in some contexts.

It's treated as relative path using cd, for example:

Command line:

c:\Users\YourUser> cd /FooBar
c:\FooBar

Here, / substitutes the drive letter.


Also, I don't see a problem at all with copying the strings, since if you print the string, the string is displayed as you wish:

Python interpreter:

>>> import os
>>> print os.path.join("c:\", "foo","bar")
c:\foo\bar
>>>


sloth
  • 99,095
  • 21
  • 171
  • 219
  • "/" is also root folder on linux, so that's not a problem. And you're right, it's not a problem when printed, but it make me upset when debugging. – ThemeZ Aug 23 '12 at 07:23
  • So when and where excatly is this a problem? Which IDE do you use? – sloth Aug 23 '12 at 07:33
  • I mean, when debugging, backslash shows as "\\" in your variable watcher right? And there're too many paths I don't want to print them all.. – ThemeZ Aug 23 '12 at 13:40
  • @ThemeZ Yeah, but which IDE are you using? Eclipse? Wing? IDLE? – sloth Aug 23 '12 at 13:43
0

I don't have enough reputation to comment, but the above answer is incorrect.

Windows has a concept of working directory and working drive. / is treated as absolute path on your current working drive, since Windows has no concept of single root. In the above example cd /FooBar goes to C:\foobar because the working drive is C:, not because C: is "root" drive or somehow special.

Here's an example:

C:\Users\user> cd /
C:\> d:
D:\> cd /Users
The system cannot find the path specified.
D:\> mkdir test
D:\> cd test
D:\test> cd c:/Users
D:\test> cd /
D:\> cd test
D:\test> c:
C:\Users\> d:
D:\test> 
Mayo
  • 113
  • 1
  • 6