Skip to main content

How to Get the Directory of the Current Script in Python

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/project

Method 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

# Full path of the current script
print(f"Script path: {os.path.abspath(__file__)}")

# Directory containing the script
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/project
Why Use os.path.abspath()?

__file__ can sometimes contain a relative path (for example, ./main.py or main.py) depending on how the script was launched. Wrapping it in os.path.abspath() converts it to an absolute path, ensuring consistent results regardless of how the script is run:

# Without abspath: may return relative path
print(__file__) # Could be: main.py

# With abspath: always returns absolute path
print(os.path.abspath(__file__)) # /home/user/project/main.py

Limitations:

  • __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

# Directory of the current script
script_dir = Path(__file__).resolve().parent
print(f"Script directory: {script_dir}")

# You can easily build paths relative to the script
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.json

The key methods:

  • .resolve() converts to an absolute path (equivalent to os.path.abspath())
  • .parent returns the parent directory
tip

pathlib is generally preferred in modern Python code because it's more readable and supports intuitive path operations with the / operator.

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/project

Limitations:

  • 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 -c flag (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/project

This 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

# Using os.path
home_os = os.path.expanduser('~')
print(f"Home (os): {home_os}")

# Using pathlib
home_pathlib = Path.home()
print(f"Home (pathlib): {home_pathlib}")

Output:

Home (os):      /home/user
Home (pathlib): /home/user

Method 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

# Using os
cwd_os = os.getcwd()
print(f"CWD (os): {cwd_os}")

# Using pathlib
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/user
Script Directory ≠ Working Directory

A common mistake is using os.getcwd() when you actually need the script's directory. If a user runs your script from a different directory, os.getcwd() returns their current location, not where your script lives:

# Running from /home/user, CWD is /home/user
cd /home/user
python project/main.py
# os.getcwd() → /home/user (NOT /home/user/project)

Always use __file__-based methods when you need paths relative to the script itself.

Practical 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.csv
from pathlib import Path

# Get the script's directory (works regardless of where you run the script from)
SCRIPT_DIR = Path(__file__).resolve().parent

# Build paths relative to the script
config_path = SCRIPT_DIR / "config.json"
data_path = SCRIPT_DIR / "data" / "input.csv"

print(f"Config: {config_path}")
print(f"Data: {data_path}")

# Read the config file
if config_path.exists():
with open(config_path) as f:
print(f"Config contents: {f.read()[:50]}...")

Method Comparison

MethodCross-PlatformWorks in REPLWorks in Frozen AppsReliability
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().