- Python 101: How to Find the Path of a Running Script
- Further Reading
- Python 3: Path of the Current Script File and Directory
- Using os.path
- File Path
- Directory
- __file__
- References and Notes
- Python 3: Path of the Current Script File and Directory
- Using os.path
- File Path
- Directory
- __file__
- References and Notes
- Python get app path
- Python get app path
- # Table of Contents
- # Get the path of the Root Project directory using Python
- # Getting a path to a file located in the project’s root directory
- # Importing the ROOT_DIR variable in another file
- # Get the path of the Root Project directory using pathlib.Path
- # Dynamically getting the root project folder from any directory
- # Using the os.curdir constant to get the root project directory
- # Additional Resources
Python 101: How to Find the Path of a Running Script
This topic is actually more complicated then it first appears. In this article, we’ll spend a little time looking at this problem and some of the solutions.
Several years ago, one of my friends on the wxPython users mailing list told me that he uses the following:
import os script_path = os.path.dirname(os.path.abspath( __file__ ))
This works for me and is what I currently use. The code above returns the absolute path, by the way. According to the documentation, it is the equivalent of
import os os.path.normpath(join(os.getcwd(), path))
I’ve also seen people recommending the following similar solution:
import os os.path.dirname(os.path.realpath(__file__))
The documentation states that realpath will return the canonical path of the specified filename, eliminating any symbolic links encountered in the path, which sounds like it may be better than the solution I’ve been using.
Regardless, as some are likely to point out, you cannot use __file__ from within IDLE / the interpreter. If you do, you’ll get the following error:
Traceback (most recent call last): File "", line 1, in __file__ NameError: name '__file__' is not defined
You’ll end up with the same error if you happen to “freeze” your application by creating an executable with something like py2exe. For cases like this, some would recommend the following as an alternative:
import os os.path.dirname(sys.argv[0])
Now this will not work if you happen to call your script from another script. I’m also pretty sure that when I tried this with a frozen application and called the executable from a shortcut, it was returning the shortcut’s path instead of the executable’s. However, I may be getting that confused with os.getcwd() which will definitely not work reliably.
The solution I ended up with for the executables I created with py2exe was this one:
import os, sys os.path.abspath(os.path.dirname(sys.argv[0]))
I’m pretty sure one of the core developers from wxPython had recommended using that, but I can’t be sure as I don’t seem to have that email any longer. Regardless, Mark Pilgrim, author of Dive Into Python, also recommends using os.path.abspath.
For now I think I will stick with either os.path.abspath or os.path.realpath for scripts and the above variation for my frozen Windows applications. I would be interested in hearing about your solution though. Let me know if you’ve found anything that works cross-platform and/or for frozen scripts.
Further Reading
Python 3: Path of the Current Script File and Directory
If you want the path of the directory that the current Python script file is in:
from pathlib import Path script_dir = Path( __file__ ).parent.absolute() print( script_dir )
Using os.path
File Path
To get the file path of the current Python script:
import os script_path = os.path.abspath( __file__ ) print( script_path )
Directory
If you want the path of the directory that the current Python script file is in:
import os script_dir = os.path.abspath( os.path.dirname( __file__ ) ) print( script_dir )
__file__
__file__ is an attribute (special variable) set by Python in modules that are loaded from files (usually, but not required to be, files that have the .py extension). The attribute is not set when you’re running code inside a Python shell (the python or python3 command line program), in a Jupyter notebook, or in other cases where the module is not loaded from a file.
Although we could use __file__ by itself:
it is not guaranteed to be an absolute path (i.e., it may be a relative path). The pathlib.Path.absolute() or os.path.abspath call ensures that it is an absolute path.
References and Notes
- The import system — Python 3 documentation
- In Python 3.4 and up, __file__ is always an absolute path «by default, with the sole exception of __main__.__file__ when a script has been executed directly using a relative path.» See Other Language Changes — What’s New in Python 3.4.
Python 3: Path of the Current Script File and Directory
If you want the path of the directory that the current Python script file is in:
from pathlib import Path script_dir = Path( __file__ ).parent.absolute() print( script_dir )
Using os.path
File Path
To get the file path of the current Python script:
import os script_path = os.path.abspath( __file__ ) print( script_path )
Directory
If you want the path of the directory that the current Python script file is in:
import os script_dir = os.path.abspath( os.path.dirname( __file__ ) ) print( script_dir )
__file__
__file__ is an attribute (special variable) set by Python in modules that are loaded from files (usually, but not required to be, files that have the .py extension). The attribute is not set when you’re running code inside a Python shell (the python or python3 command line program), in a Jupyter notebook, or in other cases where the module is not loaded from a file.
Although we could use __file__ by itself:
it is not guaranteed to be an absolute path (i.e., it may be a relative path). The pathlib.Path.absolute() or os.path.abspath call ensures that it is an absolute path.
References and Notes
- The import system — Python 3 documentation
- In Python 3.4 and up, __file__ is always an absolute path «by default, with the sole exception of __main__.__file__ when a script has been executed directly using a relative path.» See Other Language Changes — What’s New in Python 3.4.
Python get app path
The full path to executables on the system Path are discovered by Python shutil.which. On Windows, this also auto-adds the .exe extension.
A caveat on Unix-like systems (Linux, MacOS) is that shell aliases are not necessarily found by shutil.which. You should instead append the directory of the desired executable to environment variable PATH.
import shutil # None if executable not found exe = shutil.which('ls') cmd = [exe, '-l'] print(cmd)
Since shutil.which() returns None for non-found executable it is convenient for pytest.mark.skipif
For non-system utilities or other programs not on PATH, where the executable path is known, the path can be specified:
shutil.which('myexe', path=mypath)
Fixed in Python 3.8, but present in earlier Python versions is a bug that requires a string for shutil.which(. path=str(mypath)) .
Python get app path
Last updated: May 11, 2023
Reading time · 4 min
# Table of Contents
# Get the path of the Root Project directory using Python
To get the path of the root project directory:
- Use the os.path.abspath() method to get a normalized absolute path to the current file.
- Use the os.path.dirname() method to get the directory name of the path.
For example, suppose we have the following project structure.
Copied!my-project/ └── main.py └── another.py └── example.txt
You can add the following code to main.py to get the path to the root project directory.
Copied!import os # 👇️ /home/borislav/Desktop/bobbyhadz_python/main.py print(__file__) ROOT_DIR = os.path.dirname( os.path.abspath(__file__) ) # 👇️ /home/borislav/Desktop/bobbyhadz_python print(ROOT_DIR)
The __file__ variable is set to the module’s path.
We used the os.path.abspath() to get a normalized absolute version of the path.
The last step is to pass the absolute path to the os.path.dirname method.
The method returns the directory name of the supplied path.
Since our main.py file is located in the root directory of the project, the ROOT_DIR variable stores the path to the project’s root directory.
If your file is located one directory deep, you can call os.path.dirname() two times.
For example, suppose you have the following folder structure.
Copied!my-project/ src/ └── constants.py
Copied!import os ROOT_DIR = os.path.dirname( os.path.dirname( os.path.abspath(__file__) ) ) # 👇️ /home/borislav/Desktop/bobbyhadz_python print(ROOT_DIR)
Notice that we called the os.path.dirname() method twice to get the root project directory, because the constants file is located in a nested directory.
# Getting a path to a file located in the project’s root directory
The same approach can be used to get the path to a file that’s located in the project’s root directory.
Suppose we have the following folder structure and we want to get the path to the example.txt file.
Copied!my-project/ └── main.py └── another.py └── example.txt
You have to pass the ROOT_DIR variable and the example.txt string to the os.path.join() method to combine the two paths.
Copied!import os ROOT_DIR = os.path.dirname( os.path.abspath(__file__) ) # 👇️ /home/borislav/Desktop/bobbyhadz_python print(ROOT_DIR) PATH_TO_FILE_IN_ROOT_DIR = os.path.join(ROOT_DIR, 'example.txt') # 👇️ /home/borislav/Desktop/bobbyhadz_python/example.txt print(PATH_TO_FILE_IN_ROOT_DIR)
The os.path.join method takes a path and one or more path segments and joins them intelligently.
The method returns the concatenation of the supplied path and path segments.
# Importing the ROOT_DIR variable in another file
You can store your ROOT_DIR variable in a file from which you import your constants and import it into other files.
Suppose we have the following folder structure.
Copied!my-project/ └── main.py └── another.py └── example.txt
This is the code for the main.py file where the ROOT_DIR variable is defined.
Copied!import os ROOT_DIR = os.path.dirname( os.path.abspath(__file__) ) # 👇️ /home/borislav/Desktop/bobbyhadz_python print(ROOT_DIR) PATH_TO_FILE_IN_ROOT_DIR = os.path.join(ROOT_DIR, 'example.txt') # 👇️ /home/borislav/Desktop/bobbyhadz_python/example.txt print(PATH_TO_FILE_IN_ROOT_DIR)
Here is how you can import the ROOT_DIR and PATH_TO_FILE_IN_ROOT_DIR variables into a different file.
Copied!from main import ROOT_DIR, PATH_TO_FILE_IN_ROOT_DIR # 👇️ /home/borislav/Desktop/bobbyhadz_python print(ROOT_DIR) # 👇️ /home/borislav/Desktop/bobbyhadz_python/example.txt print(PATH_TO_FILE_IN_ROOT_DIR)
The another.py module is located in the same directory as the main.py file that defines the ROOT_DIR variable.
# Get the path of the Root Project directory using pathlib.Path
You can also use the Path class from the pathlib module to get the path to the root project directory.
Suppose we have the following folder structure.
Copied!my-project/ └── main.py └── src/ └── constants.py
Here is the code for constants.py .
Copied!from pathlib import Path def get_project_root_dir(): return Path(__file__).absolute().parent.parent
The module uses the pathlib.Path() class to get the absolute path to the current module and uses the parent attribute to get the logical parent of the path.
Now you can import and use the get_project_root_dir function into your main.py file.
Copied!from src.constants import get_project_root_dir ROOT_DIR = get_project_root_dir() # 👇️ /home/borislav/Desktop/bobbyhadz_python print(ROOT_DIR)
Here is an example that better illustrates how the parent attribute works.
Copied!from pathlib import Path abs_path = Path(__file__).absolute() # /home/borislav/Desktop/bobbyhadz_python/main.py print(abs_path) print(abs_path.parent) # 👉️ /home/borislav/Desktop/bobbyhadz_python print(abs_path.parent.parent) # 👉️ /home/borislav/Desktop print(abs_path.parent.parent.parent) # 👉️ /home/borislav
You can access the parent attribute multiple times to get the logical parent of each path.
Accessing the attribute once removes the filename.
The second time you access the attribute, the folder that contains the file is removed and so on.
# Dynamically getting the root project folder from any directory
This approach can be made more flexible by using a generator expression that looks for the root directory by name.
Copied!from pathlib import Path current_dir = Path(__file__) PROJECT_NAME = 'bobbyhadz_python' ROOT_DIR = next( p for p in current_dir.parents if p.parts[-1] == PROJECT_NAME ) # 👇️ /home/borislav/Desktop/bobbyhadz_python print(ROOT_DIR)
Notice that you have to specify the name of your project.
In my case, the project is named bobbyhadz-python .
The generator expression iterates over the parent directories and checks if the last part of each parent directory is equal to the project name.
If the condition is met, then we are in the root directory of the project.
# Using the os.curdir constant to get the root project directory
If you run your Python script from the root project folder, you can also:
- Use the os.curdir attribute to get a string that is used to refer to the current directory.
- Pass the string to the os.path.abspath() method.
Copied!import os ROOT_DIR = os.path.abspath(os.curdir) # 👇️ /home/borislav/Desktop/bobbyhadz_python print(ROOT_DIR)
The code sample assumes that your main.py module is placed in the root directory of your project and you run the file from the same directory.
# Additional Resources
You can learn more about the related topics by checking out the following tutorials:
I wrote a book in which I share everything I know about how to become a better, more efficient programmer.