tags:

views:

598

answers:

6

How can I find the full path to the currently running python script? That is to say, what do I have to put to achieve this:

Nirvana@bahamut:/tmp$ python baz.py
running from /tmp 
file is baz.py
+8  A: 

This will print the directory in which the script lives (as opposed to the working directory):

import os
dirname, filename = os.path.split(os.path.abspath(__file__))
print "running from", dirname
print "file is", filename

Here's how it behaves, when I put it in c:\src:

> cd c:\src
> python so-where.py
running from C:\src
file is so-where.py

> cd c:\
> python src\so-where.py
running from C:\src
file is so-where.py
RichieHindle
Note that this fails when running in py2exe, if you ever plan on using that. In that case you can import a dummy module alongside the main module and get its __file__ attribute and follow the same process, though the module will be contained in a .zip file, so you'll have to split it a bit differently.
FogleBird
@FogleBird: What's wrong with avoiding `__file__` altogether and following this: http://www.py2exe.org/index.cgi/WhereAmI ??
John Machin
Well, my way works both in py2exe and outside of it without any conditional checks. Also, py2exe docs are very scattered and hard to find what you're looking for.
FogleBird
Using `__file__` is a KLUDGE. Importing a dummy module is a KLUDGE. "you'll have to split it a bit differently" == "without any conditional checks"?? Hard to find?? here's another link: `http://www.voidspace.org.uk/python/pathutils.html#get-main-dir`
John Machin
+1  A: 
import sys, os

file = sys.argv[0]
pathname = os.path.dirname(file)
print 'running from %s' % os.path.abspath(pathname)
print 'file is %s' % file

Check os.getcwd() (docs)

Nathan
A: 

The script name will (always?) be the first index of sys.argv:

import sys
print sys.argv[0]

EDIT: just found an even easier way to find the path of your running script:

os.path.basename(sys.argv[0]
Daz
But you could be executing the script from another directory, and argv[0] would return the script's path, not yours.
willehr
@willehr: The script's path is EXACTLY what the OP requires.
John Machin
@Daz: (1) syntax error (2) if the absolute path to the script is e.g `r"C:\myfiles\fubar.py"`, the basename is `"fubar.py"` -- is that what you call "the path of your running script"?
John Machin
+1  A: 

The running file is always __file__.

Here's a demo script, named identify.py

print __file__

Here's the results

MacBook-5:Projects slott$ python StackOverflow/identify.py 
StackOverflow/identify.py
MacBook-5:Projects slott$ cd StackOverflow/
MacBook-5:StackOverflow slott$ python identify.py 
identify.py
S.Lott
+3  A: 

__file__ is NOT what you are looking for. Don't use accidental side-effects

sys.argv[0] is always the path to the script (if in fact a script has been invoked) -- see http://docs.python.org/library/sys.html#sys.argv

__file__ is the path of the currently executing file (script or module). This is accidentally the same as the script if it is accessed from the script! If you want to put useful things like locating resource files relative to the script location into a library, then you must use sys.argv[0].

Example:

C:\junk\so>type \junk\so\scriptpath\script1.py
import sys, os
print "script: sys.argv[0] is", repr(sys.argv[0])
print "script: __file__ is", repr(__file__)
print "script: cwd is", repr(os.getcwd())
import whereutils
whereutils.show_where()

C:\junk\so>type \python26\lib\site-packages\whereutils.py
import sys, os
def show_where():
    print "show_where: sys.argv[0] is", repr(sys.argv[0])
    print "show_where: __file__ is", repr(__file__)
    print "show_where: cwd is", repr(os.getcwd())

C:\junk\so>\python26\python scriptpath\script1.py
script: sys.argv[0] is 'scriptpath\\script1.py'
script: __file__ is 'scriptpath\\script1.py'
script: cwd is 'C:\\junk\\so'
show_where: sys.argv[0] is 'scriptpath\\script1.py'
show_where: __file__ is 'C:\\python26\\lib\\site-packages\\whereutils.pyc'
show_where: cwd is 'C:\\junk\\so'
John Machin
Agreed! Sorry it took my a while to come around to it; I had taken a bit of a break from the code that used I need this for. But after much deliberation, os.getcwd() did exactly what I needed and not __file__, which instead gave me the name of the file that function was in (not the file being run).
Chris Bunch
+1  A: 

I would suggest

import os, sys
print os.path.split(os.path.abspath(os.path.realpath(sys.argv[0])))[0]

This way you can safely create symbolic links to the script executable and it will still find the correct directory.

Moshev