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)
os.path.abspath('python.exe')
which on my windows machine returns 'C:\\Python27\\python.exe'
root_dir="C:/Users/folder"
with filename="data/file1.txt"
to get an absolute path? In not-windows it's easy with just os.path.join(root_dir, filename)
, but I can't find a solution in Windows.
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
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?
os.path.join()
. While it is useful to know, it does not qualify as a solution.
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')
/foo/bar/baz
if the file evaulates to /foo/bar/baz
(basically the problem you mentioned for Ansuman's answer)
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
os.path.abspath('foo')
will return (e.g.) /home/me/foo
(if i run it within /home/me
) while i really need /foo
(or C:\\foo
)
os.path.abspath()
does not seem to help me.
/etc
an absolute path? (obviously the /
prefix, but is there a programmatic way to get this suffix?)
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.
Success story sharing