views:

8774

answers:

11

I have scripts calling other script files but I need to get the filepath of the file that is currently running within the process. For example, let's say I have three files. Using 'execfile', script_1.py calls script_2.py. In turn, script_2.py calls script_3.py. How can I get the file name and path of script_3.py *from code within script_3.py* without having to pass that info as args from script_2.py? (Executing os.getcwd() returns the original starting script's filepath not the current file's.)

+6  A: 

It's not entirely clear what you mean by "the filepath of the file that is currently running within the process". sys.argv[0] usually contains the location of the script that was invoked by the Python interpreter. Check the sys documentation for more details.

As @Tim and @Pat Notz have pointed out, the __file__ attribute provides access to

the file from which the module was loaded, if it was loaded from a file

Blair Conrad
+1  A: 

I think it's just __file__ Sounds like you may also want to checkout the inspect module.

Ugh. Stupid markdown... try "underscore underscore file underscore underscore"

Pat Notz
Ahhh... execfile is tricky. See my other post about using the inspect module.
Pat Notz
+2  A: 

The "file" attribute works for both the file containing the main execution code as well as imported modules http://pyref.infogami.com/__file__

Readonly
+26  A: 

__file__ is the answer, however, it is relative to the path, so you'll need to use os.path.abspath(__file__) to get the actual path to the file

e.g.

import os

def h():
    print os.path.abspath( __file__ )
Peter Hart
A: 

Pass values for the file path and name of script_3.py as args in 'execfile' command from script_2.py to script_3.py:

# this is code in file 'script_2.py'
fname = 'script_3.py'
fpath = 'c:\\temp'
execfile(fpath + os.sep + fname, {'fname': fname, 'fpath': fpath})

(My current workaround that "works" but want to "inverse the control" so that script_3.py can provide that info instead of the calling file(s) doing it)

Ray Vega
+4  A: 

p1.py:


execfile("p2.py")

p2.py:


import inspect
print inspect.getfile( inspect.currentframe() )
Pat Notz
A: 

You can use inspect.stack()

import inspect
inspect.stack()[0]  => (<frame object at 0x00AC2AC0>, 'g:\\Python\\Test\\_GetCurrentProgram.py', 15, '<module>', ['print inspect.stack()[0]\n'], 0)
os.path.abspath (inspect.stack()[0][1]) => 'g:\\Python\\Test\\_GetCurrentProgram.py'
PabloG
A: 

__file__ as others have said. You may want to use os.realpath(__file__), however, in case it's a symlink

The code is ` os.path.realpath(__file__) `
jwhitlock
A: 
import sys

print sys.path[0]

this would print the path of the currently executing script

appusajeev
+3  A: 

The suggestions marked as best are all true if your script consists of only one file.

If you want to find out the name of the executable (i.e. the root file passed to the python interpreter for the current program) from a file that may be imported as a module, you need to do this (let's assume this is in a file named foo.py):

import inspect

print inspect.stack()[-1][1]

Because the last thing ([-1]) on the stack is the first thing that went into it (stacks are LIFO/FILO data structures).

Then in file bar.py if you import foo it'll print bar.py, rather than foo.py, which would be the value of all of these:

  • __file__
  • inspect.getfile(inspect.currentframe())
  • inspect.stack()[0][1]
Stephan Vladimir Bugaj
@Stephan: you can use backticks to format code. It will greatly improve the readability of your post.
Stephan202
A: 
import sys
print sys.argv[0]
WBAR
Unfortunately this only works if the script was called with its full path, because it only returns the "first argument" on the command line, which is the calling to the script.
Cawas