How do I get the path of the current executed file in Python?

PythonPathDirectory

Python Problem Overview


This may seem like a newbie question, but it is not. Some common approaches don't work in all cases:

sys.argv[0]

This means using path = os.path.abspath(os.path.dirname(sys.argv[0])), but this does not work if you are running from another Python script in another directory, and this can happen in real life.

__file__

This means using path = os.path.abspath(os.path.dirname(__file__)), but I found that this doesn't work:

  • py2exe doesn't have a __file__ attribute, but there is a workaround
  • When you run from IDLE with execute() there is no __file__ attribute
  • Mac OS X v10.6 (Snow Leopard) where I get NameError: global name '__file__' is not defined

Related questions with incomplete answers:

I'm looking for a generic solution, one that would work in all above use cases.

Update

Here is the result of a testcase:

Output of python a.py (on Windows)
a.py: __file__= a.py
a.py: os.getcwd()= C:\zzz

b.py: sys.argv[0]= a.py
b.py: __file__= a.py
b.py: os.getcwd()= C:\zzz
a.py
#! /usr/bin/env python
import os, sys

print "a.py: sys.argv[0]=", sys.argv[0]
print "a.py: __file__=", __file__
print "a.py: os.getcwd()=", os.getcwd()
print

execfile("subdir/b.py")
File subdir/b.py
#! /usr/bin/env python
import os, sys

print "b.py: sys.argv[0]=", sys.argv[0]
print "b.py: __file__=", __file__
print "b.py: os.getcwd()=", os.getcwd()
print
tree
C:.
|   a.py
\---subdir
        b.py

Python Solutions


Solution 1 - Python

First, you need to import from inspect and os

from inspect import getsourcefile
from os.path import abspath

Next, wherever you want to find the source file from you just use

abspath(getsourcefile(lambda:0))

Solution 2 - Python

You can't directly determine the location of the main script being executed. After all, sometimes the script didn't come from a file at all. For example, it could come from the interactive interpreter or dynamically generated code stored only in memory.

However, you can reliably determine the location of a module, since modules are always loaded from a file. If you create a module with the following code and put it in the same directory as your main script, then the main script can import the module and use that to locate itself.

some_path/module_locator.py:

def we_are_frozen():
    # All of the modules are built-in to the interpreter, e.g., by py2exe
    return hasattr(sys, "frozen")

def module_path():
    encoding = sys.getfilesystemencoding()
    if we_are_frozen():
        return os.path.dirname(unicode(sys.executable, encoding))
    return os.path.dirname(unicode(__file__, encoding))

some_path/main.py:

import module_locator
my_path = module_locator.module_path()

If you have several main scripts in different directories, you may need more than one copy of module_locator.

Of course, if your main script is loaded by some other tool that doesn't let you import modules that are co-located with your script, then you're out of luck. In cases like that, the information you're after simply doesn't exist anywhere in your program. Your best bet would be to file a bug with the authors of the tool.

Solution 3 - Python

This solution is robust even in executables:

import inspect, os.path

filename = inspect.getframeinfo(inspect.currentframe()).filename
path     = os.path.dirname(os.path.abspath(filename))

Solution 4 - Python

I was running into a similar problem, and I think this might solve the problem:

def module_path(local_function):
   ''' returns the module path without the use of __file__.  Requires a function defined
   locally in the module.
   from http://stackoverflow.com/questions/729583/getting-file-path-of-imported-module'''
   return os.path.abspath(inspect.getsourcefile(local_function))

It works for regular scripts and in IDLE. All I can say is try it out for others!

My typical usage:

from toolbox import module_path
def main():
   pass # Do stuff

global __modpath__
__modpath__ = module_path(main)

Now I use _modpath_ instead of _file_.

Solution 5 - Python

The short answer is that there is no guaranteed way to get the information you want, however there are heuristics that work almost always in practice. You might look at https://stackoverflow.com/questions/933850/how-to-find-the-location-of-the-executable-in-c. It discusses the problem from a C point of view, but the proposed solutions are easily transcribed into Python.

Solution 6 - Python

You have simply called:

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

instead of:

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

abspath() gives you the absolute path of sys.argv[0] (the filename your code is in) and dirname() returns the directory path without the filename.

Solution 7 - Python

See my answer to the question Importing modules from parent folder for related information, including why my answer doesn't use the unreliable __file__ variable. This simple solution should be cross-compatible with different operating systems as the modules os and inspect come as part of Python.

First, you need to import parts of the inspect and os modules.

from inspect import getsourcefile
from os.path import abspath

Next, use the following line anywhere else it's needed in your Python code:

abspath(getsourcefile(lambda:0))
How it works:

From the built-in module os (description below), the abspath tool is imported.

> OS routines for Mac, NT, or Posix depending on what system we're on.

Then getsourcefile (description below) is imported from the built-in module inspect.

> Get useful information from live Python objects.

  • abspath(path) returns the absolute/full version of a file path
  • getsourcefile(lambda:0) somehow gets the internal source file of the lambda function object, so returns '<pyshell#nn>' in the Python shell or returns the file path of the Python code currently being executed.

Using abspath on the result of getsourcefile(lambda:0) should make sure that the file path generated is the full file path of the Python file.
This explained solution was originally based on code from the answer at https://stackoverflow.com/questions/2632199/how-do-i-get-the-path-of-the-current-executed-file-in-python/18489147#18489147.

Solution 8 - Python

This should do the trick in a cross-platform way (so long as you're not using the interpreter or something):

import os, sys
non_symbolic=os.path.realpath(sys.argv[0])
program_filepath=os.path.join(sys.path[0], os.path.basename(non_symbolic))

sys.path[0] is the directory that your calling script is in (the first place it looks for modules to be used by that script). We can take the name of the file itself off the end of sys.argv[0] (which is what I did with os.path.basename). os.path.join just sticks them together in a cross-platform way. os.path.realpath just makes sure if we get any symbolic links with different names than the script itself that we still get the real name of the script.

I don't have a Mac; so, I haven't tested this on one. Please let me know if it works, as it seems it should. I tested this in Linux (Xubuntu) with Python 3.4. Note that many solutions for this problem don't work on Macs (since I've heard that __file__ is not present on Macs).

Note that if your script is a symbolic link, it will give you the path of the file it links to (and not the path of the symbolic link).

Solution 9 - Python

You can use Path from the pathlib module:

from pathlib import Path

# ...

Path(__file__)

You can use call to parent to go further in the path:

Path(__file__).parent

Solution 10 - Python

Simply add the following:

from sys import *
path_to_current_file = sys.argv[0]
print(path_to_current_file)

Or:

from sys import *
print(sys.argv[0])

Solution 11 - Python

If the code is coming from a file, you can get its full name

sys._getframe().f_code.co_filename

You can also retrieve the function name as f_code.co_name

Solution 12 - Python

The main idea is, somebody will run your python code, but you need to get the folder nearest the python file.

My solution is:

import os
print(os.path.dirname(os.path.abspath(__file__)))

With os.path.dirname(os.path.abspath(__file__)) You can use it with to save photos, output files, ...etc

Solution 13 - Python

import os
current_file_path=os.path.dirname(os.path.realpath('__file__'))

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionsorinView Question on Stackoverflow
Solution 1 - PythonArtOfWarfareView Answer on Stackoverflow
Solution 2 - PythonDaniel StutzbachView Answer on Stackoverflow
Solution 3 - PythonJosé Crespo BarriosView Answer on Stackoverflow
Solution 4 - PythonGarrett BergView Answer on Stackoverflow
Solution 5 - PythonDale HagglundView Answer on Stackoverflow
Solution 6 - PythondgbView Answer on Stackoverflow
Solution 7 - PythonEdwardView Answer on Stackoverflow
Solution 8 - PythonBrōtsyorfuzthrāxView Answer on Stackoverflow
Solution 9 - PythonGavriel CohenView Answer on Stackoverflow
Solution 10 - PythonH. KamranView Answer on Stackoverflow
Solution 11 - PythonAlex CohnView Answer on Stackoverflow
Solution 12 - PythonThienSuBSView Answer on Stackoverflow
Solution 13 - PythonMohamed.AbdoView Answer on Stackoverflow