48

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

$ pwd
/tmp
$ python baz.py
running from /tmp 
file is baz.py
codeforester
  • 28,846
  • 11
  • 78
  • 104
Chris Bunch
  • 80,639
  • 36
  • 120
  • 123
  • possible duplicate of [How to get full path of current file's directory in Python?](http://stackoverflow.com/questions/3430372/how-to-get-full-path-of-current-files-directory-in-python) This came earlier, but that is more explicit. Or: http://stackoverflow.com/questions/50499/in-python-how-do-i-get-the-path-and-name-of-the-file-that-is-currently-executin – Ciro Santilli新疆棉花TRUMP BAN BAD Dec 18 '14 at 21:59

8 Answers8

81

__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'
oHo
  • 41,098
  • 25
  • 141
  • 183
John Machin
  • 75,436
  • 11
  • 125
  • 178
  • 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 Sep 11 '09 at 00:07
  • 3
    As a note, if you're looking for the path to the file that holds the specific line of code being run, `__file__` is the one to use. (Such as, an `__init__.py` where you don't know where it's going to live and need to add it's `dirname()` to `sys.path` when that module is imported...) – Mark Ribau Mar 31 '12 at 01:37
  • 1
    @MarkRibau: Your first sentence is true but superflous (that's what `__file__` is defined to be). Your 2nd sentence is nothing to with the question, and is extremely puzzling: if you don't know where a module is, you can't import it, and if you can't import it you can't get its `__file__` ... – John Machin Mar 31 '12 at 07:09
  • 1
    @JohnMachin "currently running python script" is a vague question. Currently running line? Currently running `__main__`? Which is why I clarify that if you intend currently running line, `__file__` is correct. – Mark Ribau Apr 02 '12 at 23:57
  • @JohnMachin Also, you can import any module that is on `sys.path` without knowing it's path. HOWEVER, some modules (such as `p4python`) require it's own path to be in `sys.path`. I felt it silly to go around and modify everyone's systems to have that in their environment, so instead I made an `__init.py__` that will do it automatically no matter where their project root is. We do not require our developers to have identical locations for the project root, as different contractors have different hardware / harddrive capacities. – Mark Ribau Apr 02 '12 at 23:58
  • Please @JohnMachin Could you update your answer taking in account the case of freeze executable as discussed in answers about [pyInstaller](http://stackoverflow.com/a/404750/938111) and [py2exe](http://stackoverflow.com/a/2293106/938111)? – oHo Nov 12 '13 at 15:12
  • For python 3.7 (at least) sys.argv[0] doesn't return the path but the script name. – Btc Sources Aug 09 '18 at 16:54
28

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
  • 244,085
  • 44
  • 340
  • 385
  • 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 Aug 19 '09 at 01:34
  • 1
    @FogleBird: What's wrong with avoiding `__file__` altogether and following this: http://www.py2exe.org/index.cgi/WhereAmI ?? – John Machin Aug 19 '09 at 02:08
  • 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 Aug 20 '09 at 14:22
  • 1
    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 Aug 23 '09 at 10:36
9
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
  • 2,755
  • 1
  • 17
  • 16
3

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

import sys
print sys.argv[0]

An even easier way to find the path of your running script:

os.path.dirname(sys.argv[0])
David Mulder
  • 6,276
  • 10
  • 40
  • 59
WhatIsHeDoing
  • 499
  • 1
  • 6
  • 17
  • But you could be executing the script from another directory, and argv[0] would return the script's path, not yours. – ramosg Aug 18 '09 at 21:13
  • 2
    @willehr: The script's path is EXACTLY what the OP requires. – John Machin Aug 19 '09 at 00:28
  • 1
    @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 Aug 20 '09 at 13:41
3

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
  • 359,791
  • 75
  • 487
  • 757
3

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.

1

The directory of the script which python is executing is added to sys.path This is actually an array (list) which contains other paths. The first element contains the full path where the script is located (for windows).

Therefore, for windows, one can use:

import sys
path = sys.path[0]
print(path)

Others have suggested using sys.argv[0] which works in a very similar way and is complete.

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

Note that sys.argv[0] contains the full working directory (path) + filename whereas sys.path[0] is the current working directory without the filename.

I have tested sys.path[0] on windows and it works. I have not tested on other operating systems outside of windows, so somebody may wish to comment on this.

D.L
  • 661
  • 4
  • 15
0

Aside from the aforementioned sys.argv[0], it is also possible to use the __main__:

import __main__
print(__main__.__file__)

Beware, however, this is only useful in very rare circumstances; and it always creates an import loop, meaning that the __main__ will not be fully executed at that moment.

HoverHell
  • 4,186
  • 2
  • 17
  • 21