By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
464,806 Members | 1,347 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 464,806 IT Pros & Developers. It's quick & easy.

Easier way to get the "here" path?

P: n/a
I have to go into these convulsions to get the directory that the
script is in whenever I need to use relative paths. I was wondering if
you guys have a better way:

from os.path import dirname, realpath, abspath
here = dirname(realpath(abspath(__file__.rstrip("c"))))

In particular, this takes care of the case of symlinked, compiled
scripts, which is fairly common at my workplace, and I imagine in many
*nix evironments.
An illustration:
$echo "print __file__" symlinks/path.py
$ln -s symlinks/path.py
$python
>>import path
path.py
>>reload(path)
path.pyc
<module 'path' from 'path.pyc'>
>>path.__file__
'path.pyc'
>>path.__file__.rstrip("c")
'path.py'
>>from os.path import abspath, realpath
realpath(path.__file__.rstrip("c"))
'/home/bgolemon/python/symlinks/path.py'
>>realpath(abspath(path.__file__.rstrip("c")))
'/home/bgolemon/python/symlinks/symlinks/path.py'
Jul 25 '08 #1
Share this Question
Share on Google+
6 Replies

P: n/a
bukzor wrote:
I have to go into these convulsions to get the directory that the
script is in whenever I need to use relative paths. I was wondering if
you guys have a better way:
...
If you just need the current path (where it is executed) why not use
os.getcwd()
which returns a string of the absolute path to the module being executed.
$ echo "print __file__" path.py
$ ipython
In [1]: import path
path.pyc

In [2]: import os

In [3]: os.path.join(os.getcwd(), path.__file__.rstrip("c"))
Out[3]: '/home/andrew/path.py'
--
Andrew
Jul 26 '08 #2

P: n/a
bukzor wrote:
>>>from os.path import abspath, realpath
realpath(path.__file__.rstrip("c"))
'/home/bgolemon/python/symlinks/path.py'
>>>realpath(abspath(path.__file__.rstrip("c")))
'/home/bgolemon/python/symlinks/symlinks/path.py'
--
http://mail.python.org/mailman/listinfo/python-list
I find it interesting that I get something different:

In [1]: import path
path.pyc

In [2]: path.__file__
Out[2]: 'path.pyc'

In [3]: path.__file__.rstrip("c")
Out[3]: 'path.py'

In [4]: from os.path import abspath, realpath

In [5]: realpath(path.__file__.rstrip("c"))
Out[5]: '/home/andrew/sym/sym/path.py'

In [6]: realpath(abspath(path.__file__.rstrip("c")))
Out[6]: '/home/andrew/sym/sym/path.py'

I get the same thing for realpath() and realpath(abspath())
It seems to me you can just use:

In [1]: import path
path.pyc

In [2]: from os.path import abspath

In [3]: realpath(path.__file__.rstrip("c"))
Out[3]: '/home/andrew/sym/sym/path.py'

By the way, I am in /home/andrew/sym and path is symlinked from
/home/andrew/sym/sym/path.py to /home/andrew/sym/path.py

--
Andrew
Jul 26 '08 #3

P: n/a
On Jul 25, 10:08*pm, bukzor <workithar...@gmail.comwrote:
I have to go into these convulsions to get the directory that the
script is in whenever I need to use relative paths. I was wondering if
you guys have a better way:

from os.path import dirname, realpath, abspath
here = dirname(realpath(abspath(__file__.rstrip("c"))))

In particular, this takes care of the case of symlinked, compiled
scripts, which is fairly common at my workplace, and I imagine in many
*nix evironments.

An illustration:
$echo "print __file__" symlinks/path.py
$ln -s symlinks/path.py
$python>>import path
path.py
>reload(path)

path.pyc
<module 'path' from 'path.pyc'>>>path.__file__
'path.pyc'
>path.__file__.rstrip("c")
'path.py'
>from os.path import abspath, realpath
realpath(path.__file__.rstrip("c"))

'/home/bgolemon/python/symlinks/path.py'>>realpath(abspath(path.__file__.rstrip("c ")))

'/home/bgolemon/python/symlinks/symlinks/path.py'
How about:

import os
import sys
here = os.path.realpath(os.path.dirname(sys.argv[0]))

It's a little clearer. :-)
Jul 26 '08 #4

P: n/a
Andrew wrote:
bukzor wrote:
>I have to go into these convulsions to get the directory that the
script is in whenever I need to use relative paths. I was wondering if
you guys have a better way:
...
If you just need the current path (where it is executed) why not use
os.getcwd()
which returns a string of the absolute path to the module being executed.
$ echo "print __file__" path.py
$ ipython
In [1]: import path
path.pyc

In [2]: import os

In [3]: os.path.join(os.getcwd(), path.__file__.rstrip("c"))
Out[3]: '/home/andrew/path.py'
--
Andrew
I was thinking of this in the module being imported, but now that I try,
it doesn't work. It is still seeing itself from the symlink's position.

This works, in the module being imported:
$ less path.py
from os.path import realpath
here = realpath(__file__.rstrip("c"))

$ python
>>import path
path.here
'/home/andrew/sym/sym/path.py'

--
Andrew

Jul 26 '08 #5

P: n/a
On Jul 26, 9:19*am, Andrew <alif...@gmail.comwrote:
bukzor wrote:
>>from os.path import abspath, realpath
realpath(path.__file__.rstrip("c"))
'/home/bgolemon/python/symlinks/path.py'
>>realpath(abspath(path.__file__.rstrip("c")))
'/home/bgolemon/python/symlinks/symlinks/path.py'
--
http://mail.python.org/mailman/listinfo/python-list

I find it interesting that I get something different:

In [1]: import path
path.pyc

In [2]: path.__file__
Out[2]: 'path.pyc'

In [3]: path.__file__.rstrip("c")
Out[3]: 'path.py'

In [4]: from os.path import abspath, realpath

In [5]: realpath(path.__file__.rstrip("c"))
Out[5]: '/home/andrew/sym/sym/path.py'

In [6]: realpath(abspath(path.__file__.rstrip("c")))
Out[6]: '/home/andrew/sym/sym/path.py'

I get the same thing for realpath() and realpath(abspath())
It seems to me you can just use:

In [1]: import path
path.pyc

In [2]: from os.path import abspath

In [3]: realpath(path.__file__.rstrip("c"))
Out[3]: '/home/andrew/sym/sym/path.py'

By the way, I am in /home/andrew/sym and path is symlinked from
/home/andrew/sym/sym/path.py to /home/andrew/sym/path.py

--
Andrew
As you can see above, I get the wrong think if I do that. It's very
strange that we're getting different things. I'm using python 2.4,
maybe it was updated in 2.5?
Jul 28 '08 #6

P: n/a
On Jul 28, 10:34*am, bukzor <workithar...@gmail.comwrote:
On Jul 26, 9:19*am, Andrew <alif...@gmail.comwrote:
bukzor wrote:
>>>from os.path import abspath, realpath
>>>realpath(path.__file__.rstrip("c"))
'/home/bgolemon/python/symlinks/path.py'
>>>realpath(abspath(path.__file__.rstrip("c")))
'/home/bgolemon/python/symlinks/symlinks/path.py'
--
>http://mail.python.org/mailman/listinfo/python-list
I find it interesting that I get something different:
In [1]: import path
path.pyc
In [2]: path.__file__
Out[2]: 'path.pyc'
In [3]: path.__file__.rstrip("c")
Out[3]: 'path.py'
In [4]: from os.path import abspath, realpath
In [5]: realpath(path.__file__.rstrip("c"))
Out[5]: '/home/andrew/sym/sym/path.py'
In [6]: realpath(abspath(path.__file__.rstrip("c")))
Out[6]: '/home/andrew/sym/sym/path.py'
I get the same thing for realpath() and realpath(abspath())
It seems to me you can just use:
In [1]: import path
path.pyc
In [2]: from os.path import abspath
In [3]: realpath(path.__file__.rstrip("c"))
Out[3]: '/home/andrew/sym/sym/path.py'
By the way, I am in /home/andrew/sym and path is symlinked from
/home/andrew/sym/sym/path.py to /home/andrew/sym/path.py
--
Andrew

As you can see above, I get the wrong think if I do that. It's very
strange that we're getting different things. I'm using python 2.4,
maybe it was updated in 2.5?
After doing a little testing, it seems that realpath was in fact
improved between 2.4 and 2.5. I need to stick with 2.4, so the
abspath() call is still necessary for me.

Regardless, the answer to my question is that there's no good built-in
way to do this. Even the code above fails for some cases (say the
symlink is named just "c"), making the problem non-trivial. To me,
this is a failure of python's "batteries included". Is this worthy of
a PEP? I'd like to add something like "__absfile__" or maybe
"os.path.absolute_script_path()".

Sample implementation:
def scriptpath():
from inspect import currentframe
file = currentframe().f_back.f_locals.get('__file__', None)
if file.endswith(".pyc"): file = file.rstrip("c")
from os.path import realpath, abspath

return realpath(abspath(file))
Testing:
~/python>ls -l foo.py* c sym/*
lrwxrwxrwx 1 bgolemon asic 10 Jul 28 10:46 c -sym/
bar.py*
lrwxrwxrwx 1 bgolemon asic 10 Jul 28 10:38 foo.py -sym/
bar.py*
-rw-rw-r-- 1 bgolemon asic 149 Jul 28 10:57 foo.pyc
-rwxrwx--- 1 bgolemon asic 76 Jul 28 10:53 sym/bar.py*
-rw-rw-r-- 1 bgolemon asic 149 Jul 28 10:58 sym/bar.pyc

~/python>cat sym/bar.py
#!/usr/bin/env python

from scriptpath import scriptpath
print scriptpath()
~/python>./c
/home/bgolemon/python/sym/bar.py

~/python>./sym/bar.py
/home/bgolemon/python/sym/bar.py

~/python>./foo.py
/home/bgolemon/python/sym/bar.py

~/python>python
>>import foo
/home/bgolemon/python/sym/bar.py

~/python>cd sym/
~/python/sym>python
>>import bar
/home/bgolemon/python/sym/bar.py
--Buck
Jul 28 '08 #7

This discussion thread is closed

Replies have been disabled for this discussion.