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 th
Most of these answers were written in Python version 2.x or earlier. In Python 3.x the syntax for the print function has changed to require parentheses, i.e. print().
So, this earlier high score answer from user13993 in Python 2.x:
import inspect, os
print inspect.getfile(inspect.currentframe()) # script filename (usually with path)
print os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) # script directory
Becomes in Python 3.x:
import inspect, os
print(inspect.getfile(inspect.currentframe())) # script filename (usually with path)
print(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) ) # script directory
Update 2018-11-28:
Here is a summary of experiments with Python 2 and 3. With
main.py - runs foo.py
foo.py - runs lib/bar.py
lib/bar.py - prints filepath expressions
| Python | Run statement | Filepath expression |
|--------+---------------------+----------------------------------------|
| 2 | execfile | os.path.abspath(inspect.stack()[0][1]) |
| 2 | from lib import bar | __file__ |
| 3 | exec | (wasn't able to obtain it) |
| 3 | import lib.bar | __file__ |
For Python 2, it might be clearer to switch to packages so can use from lib import bar
- just add empty __init__.py
files to the two folders.
For Python 3, execfile
doesn't exist - the nearest alternative is exec(open(<filename>).read())
, though this affects the stack frames. It's simplest to just use import foo
and import lib.bar
- no __init__.py
files needed.
See also Difference between import and execfile
Original Answer:
Here is an experiment based on the answers in this thread - with Python 2.7.10 on Windows.
The stack-based ones are the only ones that seem to give reliable results. The last two have the shortest syntax, i.e. -
print os.path.abspath(inspect.stack()[0][1]) # C:\filepaths\lib\bar.py
print os.path.dirname(os.path.abspath(inspect.stack()[0][1])) # C:\filepaths\lib
Here's to these being added to sys as functions! Credit to @Usagi and @pablog
Based on the following three files, and running main.py from its folder with python main.py
(also tried execfiles with absolute paths and calling from a separate folder).
C:\filepaths\main.py: execfile('foo.py')
C:\filepaths\foo.py: execfile('lib/bar.py')
C:\filepaths\lib\bar.py:
import sys
import os
import inspect
print "Python " + sys.version
print
print __file__ # main.py
print sys.argv[0] # main.py
print inspect.stack()[0][1] # lib/bar.py
print sys.path[0] # C:\filepaths
print
print os.path.realpath(__file__) # C:\filepaths\main.py
print os.path.abspath(__file__) # C:\filepaths\main.py
print os.path.basename(__file__) # main.py
print os.path.basename(os.path.realpath(sys.argv[0])) # main.py
print
print sys.path[0] # C:\filepaths
print os.path.abspath(os.path.split(sys.argv[0])[0]) # C:\filepaths
print os.path.dirname(os.path.abspath(__file__)) # C:\filepaths
print os.path.dirname(os.path.realpath(sys.argv[0])) # C:\filepaths
print os.path.dirname(__file__) # (empty string)
print
print inspect.getfile(inspect.currentframe()) # lib/bar.py
print os.path.abspath(inspect.getfile(inspect.currentframe())) # C:\filepaths\lib\bar.py
print os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) # C:\filepaths\lib
print
print os.path.abspath(inspect.stack()[0][1]) # C:\filepaths\lib\bar.py
print os.path.dirname(os.path.abspath(inspect.stack()[0][1])) # C:\filepaths\lib
print
import os
os.path.dirname(os.path.abspath(__file__))
No need for inspect or any other library.
This worked for me when I had to import a script (from a different directory then the executed script), that used a configuration file residing in the same folder as the imported script.
I have always just used the os feature of Current Working Directory, or CWD. This is part of the standard library, and is very easy to implement. Here is an example:
import os
base_directory = os.getcwd()
I have a script that must work under windows environment. This code snipped is what I've finished with:
import os,sys
PROJECT_PATH = os.path.abspath(os.path.split(sys.argv[0])[0])
it's quite a hacky decision. But it requires no external libraries and it's the most important thing in my case.
You can use inspect.stack()
import inspect,os
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'