How do you properly determine the current script directory? How do you properly determine the current script directory? python python

How do you properly determine the current script directory?


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

is indeed the best you're going to get.

It's unusual to be executing a script with exec/execfile; normally you should be using the module infrastructure to load scripts. If you must use these methods, I suggest setting __file__ in the globals you pass to the script so it can read that filename.

There's no other way to get the filename in execed code: as you note, the CWD may be in a completely different place.


If you really want to cover the case that a script is called via execfile(...), you can use the inspect module to deduce the filename (including the path). As far as I am aware, this will work for all cases you listed:

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


#!/usr/bin/env pythonimport inspectimport osimport sysdef get_script_dir(follow_symlinks=True):    if getattr(sys, 'frozen', False): # py2exe, PyInstaller, cx_Freeze        path = os.path.abspath(sys.executable)    else:        path = inspect.getabsfile(get_script_dir)    if follow_symlinks:        path = os.path.realpath(path)    return os.path.dirname(path)print(get_script_dir())

It works on CPython, Jython, Pypy. It works if the script is executed using execfile() (sys.argv[0] and __file__ -based solutions would fail here). It works if the script is inside an executable zip file (/an egg). It works if the script is "imported" (PYTHONPATH=/path/to/library.zip python -mscript_to_run) from a zip file; it returns the archive path in this case. It works if the script is compiled into a standalone executable (sys.frozen). It works for symlinks (realpath eliminates symbolic links). It works in an interactive interpreter; it returns the current working directory in this case.