4

I need to resolve a disparity between the separator that sys.path is providing, and the separator that os.path.join is using.

I mimicked this Esri method (Techniques for sharing Python scripts) to make my script portable. It is being used in Windows for now, but will eventually live on a Linux server; I need to let Python determine the appropriate slash.

What they suggest:

# Get the pathname to this script
scriptPath = sys.path[0]

# Get the pathname to the ToolShare folder
toolSharePath = os.path.dirname(scriptPath)

# Now construct pathname to the ToolData folder
toolDataPath = os.path.join(toolSharePath, "ToolData")
print "ToolData folder: " + toolDataPath

But this outputs ToolData folder: C:/gis\ToolData -- and obviously the mixed slashes aren't going to work.

This Question (mixed slashes with os.path.join on windows) includes the basic approach to a solution:

check your external input (the input you apparently do not control the format of) before putting it in os.path.join. This way you make sure that os.path.join does not make bad decisions based on possibly bad input

However, I'm unsure how to ensure that it will work cross-platform. If I use .replace("/","\\") on the sys.path[0] result, that's great for Windows, but isn't that going to cause the same mixed-slash problem once I transition to Unix?

Community
  • 1
  • 1
Erica
  • 2,399
  • 5
  • 26
  • 34
  • Is `pathlib` an option? It's new in Python 3.4, and does not exist in Python 2.7. – chepner Sep 03 '14 at 15:43
  • I _think_ that I'm stuck with Python 2.7 because of a bunch of ArcPy functions that I use (and/or we only have 2.7 on the server). – Erica Sep 03 '14 at 15:44
  • Python can use forward slashes for Windows paths, so `sys.path[0].replace(r'\', '/')` might be your best be for cross-platform functionality. – chepner Sep 03 '14 at 15:48

3 Answers3

7

How about using os.path.normpath()?

>>> import os
>>> os.path.normpath(r'c:\my/path\to/something.py')
'c:\\my\\path\\to\\something.py'

Also worth mentioning: the Windows path API doesn't care whether forward or back slashes are used. Usually it's the fault of program that doesn't handle the slashing properly. For example, in python:

with open(r'c:/path/to/my/file.py') as f:
    print f.read()

will work.

OozeMeister
  • 4,638
  • 1
  • 23
  • 31
2

After reading the documentation and trying a lot of variations:

The os.path.abspath function can "clean" the slashes, so whichever direction slash sys.path[0] decides to use, the slashes will be replaced with the preferred separator.

scriptPath = sys.path[0]
toolDataPath = os.path.join(scriptPath, "ToolData")

Result: C:/gis\ToolData

scriptPath = sys.path[0]
toolSharePath = os.path.abspath(scriptPath)
# or, in one line: toolSharePath = os.path.abspath(sys.path[0])
toolDataPath = os.path.join(toolSharePath, "ToolData")

Result: C:\gis\ToolData

Erica
  • 2,399
  • 5
  • 26
  • 34
  • 1
    Do read that documentation carefully: *On most platforms, this is equivalent to calling the function `normpath()` ...*. Just call `os.path.normpath()` **directly** unless you also must make the path absolute. – Martijn Pieters Nov 26 '18 at 15:41
0

There is an os.sep character in Python, which stores your OS's preferred folder separating character. Perhaps you could perform a manual string join using that?

On Linux:

>>> import os
>>> os.sep
'/'

https://docs.python.org/2/library/os.html#os.sep

TheSoundDefense
  • 6,753
  • 1
  • 30
  • 42
  • 2
    The problem is that `os.sep` (in Windows, a backslash) doesn't match what `sys.path[0]` is using (a forward slash). It might do on Linux (haven't checked), but I would like it to operate cleanly in either platform. – Erica Sep 03 '14 at 15:40