1

When I get the os.path.dirname() of a file on Windows, it uses the / character (gets converted to \ by Windows), but then when I os.path.join() that path with other things, it uses the \ character (as expected).

import os

cwd = os.path.dirname(__file__)
print(cwd)                            # C:/Users/me/Documents/dir1
parent_dir = os.path.join(cwd, '..')
print(parent_dir)                     # C:/Users/me/Documents/dir1\..

Windows handles this just fine. As per MSDN:

File I/O functions in the Windows API convert "/" to "\" as part of converting the name to an NT-style name, except when using the "\\?\" prefix as detailed in the following sections.

But why does the use of both slashes occuring in the first place?

EDITS:

I run the command using python myfile.py from Cygwin shell.

I am using the Anaconda3 distribution, which is installed at C:\Users\me\AppData\Local\Continuum\Anaconda3\python.exe.

λ which python
/cygdrive/c/Users/me/AppData/Local/Continuum/Anaconda3/python
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
Aaron
  • 2,367
  • 3
  • 25
  • 33
  • 2
    cannot reproduce the slashes on windows (first output). How do you run your python file? – Jean-François Fabre Feb 22 '17 at 20:12
  • @Jean-FrançoisFabre I am using Anaconda, see my edit. – Aaron Feb 22 '17 at 20:18
  • 1
    are you running it from cygwin by chance? – Jean-François Fabre Feb 22 '17 at 20:30
  • @Jean-FrançoisFabre it is running from `/cygdrive/c` – Aaron Feb 22 '17 at 20:34
  • edited (added "from Cygwin shell"). Hope it's OK. – Jean-François Fabre Feb 22 '17 at 20:38
  • There are more places than just ``\\?\`` paths where you can be bitten by using forward slashes in Windows (e.g. command-line arguments and anything that uses native paths under the hood; such as ``Global\`` kernel object names and registry paths). For the filesystem API, forward slash is allowed because runtime library functions such as `RtlDosPathNameToNtPathName_U_WithStatus` do the conversion for you. But for consistency it's often better to just do it yourself. `pathlib` in Python 3 handles this for you, and in 3.6 it's broadly supported by the standard library. – Eryk Sun Feb 22 '17 at 21:57

1 Answers1

3

Since you're running from cygwin, the paths are not native, but altered for cygwin to be able to work properly (MSYS does the same).

So as a side effect, when python asks for current file, it is returned with slashes.

BUT anaconda is still a native windows distribution, which explains that you get \ (native os.sep) when joining strings.

To get __file__ path with native separators (\ here), just do:

os.path.normpath(__file__)
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219