constructing absolute path with os.path.join()

PythonPathAbsolute Path

Python Problem Overview


I'd like to construct an absolute path in python, while at the same time staying fairly oblivious of things like path-separator.

edit0: for instance there is a directory on the root of my filesystem /etc/init.d (or C:\etc\init.d on w32), and I want to construct this only from the elements etc and init.d (on w32, I probably also need a disk-ID, like C:)

In order to not having to worry about path-separators, os.join.path() is obviously the tool of choice. But it seems that this will only ever create relative paths:

 print("MYPATH: %s" % (os.path.join('etc', 'init.d'),)
 MYPATH: etc/init.d

Adding a dummy first-element (e.g. '') doesn't help anything:

 print("MYPATH: %s" % (os.path.join('', 'etc', 'init.d'),)
 MYPATH: etc/init.d

Making the first element absolute obviously helps, but this kind of defeats the idea of using os.path.join()

 print("MYPATH: %s" % (os.path.join('/etc', 'init.d'),)
 MYPATH: /etc/init.d

edit1: using os.path.abspath() will only try to convert a relative path into an absolute path. e.g. consider running the following in the working directory /home/foo:

 print("MYPATH: %s" % (os.path.abspath(os.path.join('etc', 'init.d')),)
 MYPATH: /home/foo/etc/init.d

So, what is the standard cross-platform way to "root" a path?

 root = ??? # <--
 print("MYPATH: %s" % (os.path.join(root, 'etc', 'init.d'),)
 MYPATH: /etc/init.d

edit2: the question really boils down to: since the leading slash in /etc/init.d makes this path an absolute path, is there a way to construct this leading slash programmatically? (I do not want to make assumptions that a leading slash indicates an absolute path)

Python Solutions


Solution 1 - Python

Using os.sep as root worked for me:

path.join(os.sep, 'python', 'bin')

Linux: /python/bin

Windows: \python\bin

Adding path.abspath() to the mix will give you drive letters on Windows as well and is still compatible with Linux:

path.abspath(path.join(os.sep, 'python', 'bin'))

Linux: /python/bin

Windows: C:\python\bin

Solution 2 - Python

I think you can use os.path.normpath. Here's what I get on Windows:

>>> os.path.normpath("/etc/init.d")
'\\etc\\init.d'

I'm not sure exactly what the right thing to do with the drive prefix is, but I think leaving it off means something like "keep using the drive I'm on now," which is probably what you want. Maybe someone more familiar with Windows can clarify?

Solution 3 - Python

so the solution i came up with, is to construct the root of the filesystem by following a given file to it's root:

def getRoot(file=None):
  if file is None:
      file='.'
  me=os.path.abspath(file)
  drive,path=os.path.splitdrive(me)
  while 1:
    path,folder=os.path.split(path)
    if not folder:
       break
  return drive+path

 os.path.join(getRoot(), 'etc', 'init.d')

Solution 4 - Python

So you can do a check for running os by sys.platfrom

on windows

>>> sys.platform
'win32'

on linux

>>> sys.platform
'linux2'

then

if sys.platform == 'win32':
    ROOT = os.path.splitdrive(os.path.abspath('.'))[0]
elif sys.platform == 'linux2':
    ROOT = os.sep

Please note that 'linux2' may not cover all linux distros

Solution 5 - Python

you could try with os.path.splitdrive to get the name of your drive/filesystem, then join this with your foo string.

http://docs.python.org/2/library/os.path.html#os.path.splitdrive

something like (untested!)

(drive, tail) = os.path.splitdrive(os.getcwd())
os.path.join(drive, 'foo')

should do the trick.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuml&#228;uteView Question on Stackoverflow
Solution 1 - Pythongirardc79View Answer on Stackoverflow
Solution 2 - PythonJack O'ConnorView Answer on Stackoverflow
Solution 3 - PythonumläuteView Answer on Stackoverflow
Solution 4 - PythonAnsuman BebartaView Answer on Stackoverflow
Solution 5 - PythonChristophView Answer on Stackoverflow