When writing Python scripts, you often need to know the directory where the current script is located: for example, to read configuration files, load data, or construct paths relative to the script. Python provides several ways to get this information, each with different trade-offs.
In this guide, we'll cover the most reliable methods, explain when to use each one, and highlight their limitations.
Quick Answer
The most common and reliable approach:
import os
script_dir = os.path.dirname(os.path.abspath(__file__))
print(script_dir)Output (if script is at /home/user/project/main.py):
/home/user/projectMethod 1: Using __file__ with os.path
The __file__ attribute contains the path of the currently executing script. Combine it with os.path.dirname() and os.path.abspath() to get the absolute directory path:
import os
print(f"Script path: {os.path.abspath(__file__)}")
script_dir = os.path.dirname(os.path.abspath(__file__))
print(f"Script directory: {script_dir}")Output:
Script path: /home/user/project/main.py
Script directory: /home/user/projectLimitations:
__file__is not available in interactive interpreters (Python REPL, IDLE, Jupyter notebooks).__file__is not defined in frozen executables (such as PyInstaller bundles) or some statically linked C modules.
Method 2: Using pathlib.Path (Modern Python)
Python 3.4+ introduced pathlib, which provides an object-oriented approach to path handling:
from pathlib import Path
script_dir = Path(__file__).resolve().parent
print(f"Script directory: {script_dir}")
data_file = script_dir / "data" / "config.json"
print(f"Config path: {data_file}")Output:
Script directory: /home/user/project
Config path: /home/user/project/data/config.jsonThe key methods:
.resolve()converts to an absolute path (equivalent toos.path.abspath()).parentreturns the parent directory
Method 3: Using sys.argv[0]
sys.argv[0] contains the script name as it was invoked from the command line:
import os
import sys
script_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
print(f"Script directory: {script_dir}")Output:
Script directory: /home/user/projectLimitations:
sys.argv[0]may be an empty string when running from an interactive interpreter.- If the script is invoked in an unusual way (such as via
exec()or certain embedding scenarios),sys.argv[0]may not contain the expected path. - When running with the
-cflag (python -c "..."),sys.argv[0]is'-c'.
Method 4: Using inspect.getsourcefile()
The inspect module can retrieve the source file of any Python object. By passing a dummy object (like a lambda), you get the current script's path:
import os
from inspect import getsourcefile
script_dir = os.path.dirname(os.path.abspath(getsourcefile(lambda: 0)))
print(f"Script directory: {script_dir}")Output:
Script directory: /home/user/projectThis method is considered one of the most robust because it works in more edge cases than __file__ alone. However, it requires importing the inspect module and the lambda trick makes the code less immediately readable.
Method 5: Getting the User's Home Directory
Sometimes you need the home directory rather than the script directory:
import os
from pathlib import Path
home_os = os.path.expanduser('~')
print(f"Home (os): {home_os}")
home_pathlib = Path.home()
print(f"Home (pathlib): {home_pathlib}")Output:
Home (os): /home/user
Home (pathlib): /home/userMethod 6: Getting the Current Working Directory
The current working directory (CWD) is the directory from which the script was run, which is not necessarily the same as the script's own directory:
import os
from pathlib import Path
cwd_os = os.getcwd()
print(f"CWD (os): {cwd_os}")
cwd_pathlib = Path.cwd()
print(f"CWD (pathlib): {cwd_pathlib}")Output (if you ran python /home/user/project/main.py from /home/user):
CWD (os): /home/user
CWD (pathlib): /home/userPractical Example: Loading a File Relative to the Script
A common use case is loading a configuration or data file that sits next to your script:
project/
├── main.py
├── config.json
└── data/
└── input.csvfrom pathlib import Path
SCRIPT_DIR = Path(__file__).resolve().parent
config_path = SCRIPT_DIR / "config.json"
data_path = SCRIPT_DIR / "data" / "input.csv"
print(f"Config: {config_path}")
print(f"Data: {data_path}")
if config_path.exists():
with open(config_path) as f:
print(f"Config contents: {f.read()[:50]}...")Method Comparison
| Method | Cross-Platform | Works in REPL | Works in Frozen Apps | Reliability |
|---|---|---|---|---|
Path(__file__).resolve().parent |
✅ | ❌ | ❌ | ⭐⭐⭐⭐ |
os.path.dirname(os.path.abspath(__file__)) |
✅ | ❌ | ❌ | ⭐⭐⭐⭐ |
os.path.dirname(os.path.abspath(sys.argv[0])) |
✅ | ❌ | ✅ | ⭐⭐⭐ |
inspect.getsourcefile(lambda: 0) |
✅ | ❌ | ❌ | ⭐⭐⭐⭐⭐ |
os.getcwd() / Path.cwd() |
✅ | ✅ | ✅ | ⭐⭐ (different purpose) |
Path.home() / os.path.expanduser('~') |
✅ | ✅ | ✅ | ⭐⭐⭐⭐ (different purpose) |
Conclusion
To get the directory of the current Python script, use Path(__file__).resolve().parent (modern pathlib approach) or os.path.dirname(os.path.abspath(__file__)) (traditional os.path approach).
- Both are reliable, cross-platform solutions that work regardless of how or from where the script is executed.
- Avoid using
os.getcwd()for this purpose: it returns the working directory (where the user launched the script from), not the script directory (where the script file is located).
For the most robust solution across edge cases, use inspect.getsourcefile().