python - How to reliably open a file in the same directory as the currently running script

ID : 20148

viewed : 20

Tags : pythondirectorypython

Top 5 Answer for python - How to reliably open a file in the same directory as the currently running script

vote vote

99

I always use:

__location__ = os.path.realpath(     os.path.join(os.getcwd(), os.path.dirname(__file__))) 

The join() call prepends the current working directory, but the documentation says that if some path is absolute, all other paths left of it are dropped. Therefore, getcwd() is dropped when dirname(__file__) returns an absolute path.

Also, the realpath call resolves symbolic links if any are found. This avoids troubles when deploying with setuptools on Linux systems (scripts are symlinked to /usr/bin/ -- at least on Debian).

You may the use the following to open up files in the same folder:

f = open(os.path.join(__location__, 'bundled-resource.jpg')) # ... 

I use this to bundle resources with several Django application on both Windows and Linux and it works like a charm!

vote vote

81

To quote from the Python documentation:

As initialized upon program startup, the first item of this list, path[0], is the directory containing the script that was used to invoke the Python interpreter. If the script directory is not available (e.g. if the interpreter is invoked interactively or if the script is read from standard input), path[0] is the empty string, which directs Python to search modules in the current directory first. Notice that the script directory is inserted before the entries inserted as a result of PYTHONPATH.

If you are running the script from the terminal, sys.path[0] is what you are looking for.

However, if you have:

barpath/bar.py     import foopath.foo  foopath/foo.py     print sys.path[0]  # you get barpath 

So watch out!

vote vote

77

On Python 3.4, the pathlib module was added, and the following code will reliably open a file in the same directory as the current script:

from pathlib import Path  p = Path(__file__).with_name('file.txt') with p.open('r') as f:     print(f.read()) 

You can also use parent.absolute() to get directory value as a string if you need it in order to use some kind of open-like API:

p = Path(__file__) dir_abs = p.parent.absolute()  # Will return the executable directory absolute path 
vote vote

62

Ok here is what I do

sys.argv is always what you type into the terminal or use as the file path when executing it with python.exe or pythonw.exe

For example you can run the file text.py several ways, they each give you a different answer they always give you the path that python was typed.

    C:\Documents and Settings\Admin>python test.py     sys.argv[0]: test.py     C:\Documents and Settings\Admin>python "C:\Documents and Settings\Admin\test.py"     sys.argv[0]: C:\Documents and Settings\Admin\test.py 

Ok so know you can get the file name, great big deal, now to get the application directory you can know use os.path, specifically abspath and dirname

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

That will output this:

   C:\Documents and Settings\Admin\ 

it will always output this no matter if you type python test.py or python "C:\Documents and Settings\Admin\test.py"

The problem with using __file__ Consider these two files test.py

import sys import os  def paths():         print "__file__: %s" % __file__         print "sys.argv: %s" % sys.argv[0]          a_f = os.path.abspath(__file__)         a_s = os.path.abspath(sys.argv[0])          print "abs __file__: %s" % a_f         print "abs sys.argv: %s" % a_s  if __name__ == "__main__":     paths() 

import_test.py

import test import sys  test.paths()  print "--------" print __file__ print sys.argv[0] 

Output of "python test.py"

C:\Documents and Settings\Admin>python test.py __file__: test.py sys.argv: test.py abs __file__: C:\Documents and Settings\Admin\test.py abs sys.argv: C:\Documents and Settings\Admin\test.py 

Output of "python test_import.py"

C:\Documents and Settings\Admin>python test_import.py __file__: C:\Documents and Settings\Admin\test.pyc sys.argv: test_import.py abs __file__: C:\Documents and Settings\Admin\test.pyc abs sys.argv: C:\Documents and Settings\Admin\test_import.py -------- test_import.py test_import.py 

So as you can see file gives you always the python file it is being run from, where as sys.argv[0] gives you the file that you ran from the interpreter always. Depending on your needs you will need to choose which one best fits your needs.

vote vote

60

I commonly use the following. It works for testing and probably other use cases as well.

with open(os.path.join(os.path.dirname(__file__), 'some_file.txt'), 'r') as f:

This answer is recommended in https://stackoverflow.com/questions/10174211/how-to-make-an-always-relative-to-current-module-file-path


Top 3 video Explaining python - How to reliably open a file in the same directory as the currently running script

Related QUESTION?