devcrea

How to Get the Current Directory in Python

Learn the exact difference between os.getcwd() and __file__ to avoid broken relative paths in production. See modern pathlib examples for directory operations.

// The short answer

Use Path.cwd() or os.getcwd() when you need the directory from which Python was launched, not the directory containing the script. For the script's own location, use Path(__file__).resolve().parent; this distinction prevents FileNotFoundError when a program is started from a different working directory, an IDE, a scheduler, or a production service.

Full walkthrough, edge cases and why it works
In this guide · 5 sections
  1. 01The Quick Answer: os.getcwd() vs. pathlib.Path.cwd()
  2. 02The Real Trap: Where You Run It vs. Where It Lives
  3. 03The Modern Way: Handling Paths with pathlib
  4. 04The Old-School Way: Sticking with the os Module
  5. 05Catching Nasty Path Bugs in Production

Almost every developer has hit that sudden FileNotFoundError right after shipping code to a server. Nine times out of ten, it boils down to one simple mix-up: os.getcwd() doesn't care where your code physically lives on disk - it only cares where you were standing in the terminal when you hit Enter. Dodging this headache means dropping the habit of relying on your terminal's current location and anchoring your paths directly to the file itself.

What you're trying to do Modern way (Python 3.4+) Old-school way
Check where the command was run Path.cwd() os.getcwd()
Find the folder your script lives in Path(__file__).resolve().parent os.path.dirname(os.path.realpath(__file__))
Jump to a different folder Don't do this (anti-pattern) os.chdir(path)

The Quick Answer: os.getcwd() vs. pathlib.Path.cwd()

If all you want is to inspect the folder where someone fired up Python, the standard library gives you two solid options. The venerable os module has been doing this for decades, while pathlib handles it through clean, object-oriented paths instead of plain strings. At the end of the day, both give you the exact same filesystem string.

Python

code10 lines
import os
from pathlib import Path

# The classic approach
current_dir_os = os.getcwd()
print(current_dir_os)

# The modern pathlib approach
current_dir_pathlib = Path.cwd()
print(current_dir_pathlib)

The Real Trap: Where You Run It vs. Where It Lives

This subtle distinction causes more broken scripts than almost anything else in Python path handling. The current working directory isn't wired to the .py file you're running; it is tied directly to the terminal prompt that kicked off the process.

Why os.getcwd() Will Mislead You

Say you have a script sitting cleanly at /home/user/app/main.py. You open your shell, but your prompt happens to be sitting at /var/www/. From there, you trigger the script by running python /home/user/app/main.py.

If you print os.getcwd() inside that script, you won't get your app folder - you'll get /var/www/. Python assumes you want relative file lookups resolved against the folder you started from, which immediately breaks every relative lookup for config files, database assets, or local templates. If you manage environment variables across different deployment environments, keeping these path references stable becomes even more critical.

Anchoring to the Actual File with file

If you want to grab files bundled alongside your code without praying the terminal is in the right place, you have to build paths relative to the file itself. Python gives us __file__ for exactly that reason - it always points right back to the file currently executing.

Python

code5 lines
from pathlib import Path

# Locks down the folder where this specific script lives
script_dir = Path(__file__).resolve().parent
print(script_dir)

Throwing .resolve() into the chain guarantees you get a clean, absolute path while stripping out symlinks along the way. That gives you a completely rock-solid base to construct all your internal paths.

The Modern Way: Handling Paths with pathlib

If you're writing modern Python, pathlib is pretty much the tool you want by default. It replaces messy string manipulations and nested function calls with methods that chain together naturally and make total sense when you read them back.

Climbing Up to Parent Folders

You don't have to nest functions inside functions just to walk up a project directory anymore. The .parent property handles it gracefully, and you can simply chain it as many times as needed to walk up your project hierarchy.

Python

code7 lines
from pathlib import Path

current_file = Path(__file__).resolve()
parent_dir = current_file.parent
grandparent_dir = current_file.parent.parent

print(parent_dir)

Joining Paths Cleanly (pathlib vs. os.path.join)

Stitching paths together with string formatting usually ends with double slashes, missing delimiters, or backslash nightmares on Windows. The pathlib library neatly sidesteps this by overloading the / operator, letting you build cross-platform paths that work everywhere out of the box.

Python

code6 lines
from pathlib import Path

base_dir = Path(__file__).resolve().parent
config_file = base_dir / 'config' / 'settings.json'

print(config_file)

The Old-School Way: Sticking with the os Module

You're still going to see the classic os module all over legacy codebases and older tutorials. It works fine, but remember that you're juggling raw text strings rather than rich path objects.

Combining os.path.dirname and os.path.realpath

If you're stuck on an older codebase without pathlib, reaching the script folder means stacking a couple of os.path calls together. You use realpath to follow any symlinks to the true file, then wrap it in dirname to discard the filename and keep the directory.

Python

code5 lines
import os

# The classic pattern for grabbing the script's folder
script_dir = os.path.dirname(os.path.realpath(__file__))
print(script_dir)

Changing Working Directories with os.chdir

If you really need to, you can yank the running Python process over to a completely different folder using os.chdir(path). Every relative path checked afterward will immediately pivot to that new spot.

Python

code5 lines
import os

print(os.getcwd())
os.chdir('/tmp')
print(os.getcwd())

A quick word of caution: treat os.chdir as a last resort in production code. Changing the global working directory alters state for the whole process, which can quietly break background threads, third-party loggers, or other modules that expected the original working directory to stay put.

Catching Nasty Path Bugs in Production

Most path bugs stay completely invisible on your local machine and only rear their heads once your app lands on a staging or production box.

Cron Jobs and the Silent Working Directory Trap

Scheduled cron jobs run in a bare-bones environment that rarely looks like your everyday terminal. By default, cron usually executes from the user's home directory instead of your project's folder. If you're on a remote Linux host trying to figure out where files ended up, a quick check with the find command will tell you the ground truth.

If your code relies on os.getcwd() here, the script will crash in the background without giving you an obvious clue. Tying your paths to __file__ keeps automated jobs safe every time.

Why Code Breaks Outside VS Code or PyCharm

Modern IDEs do you a sneaky favor: whenever you hit that green "Run" button, they quietly set the working directory straight to your project root. Everything runs like a charm on your laptop. But when you wrap that code into a Docker image, an automated service, or a systemd daemon, that safety net disappears and the code throws an immediate crash.

Anchoring your lookups directly to __file__ wipes out those differences completely, keeping your files exactly where Python expects them no matter how the process was started. Keep the cheat sheet up top handy whenever a path starts acting strangely.

Quick answers

Frequently asked questions

What is the difference between os.getcwd() and __file__ in Python?

os.getcwd() returns the directory where you ran the Python command, not where the script file is saved. __file__ always points to the script file itself. If you run python /home/user/app/main.py from /var/www/, os.getcwd() returns /var/www/ while Path(__file__).resolve().parent returns /home/user/app/.

How do I get the directory where my Python script is located?

Use Path(__file__).resolve().parent from the pathlib module. This gives you the absolute path of the folder containing your script, regardless of where you run it from. The legacy equivalent is os.path.dirname(os.path.realpath(__file__)).

How to change the current working directory in Python?

Use os.chdir('/path/to/dir') to change the working directory. Be careful with this in larger applications since it modifies a global state that affects all subsequent file operations in the process, including code in other modules.

How to get the parent directory in Python?

With pathlib, use Path(__file__).resolve().parent for the immediate parent, and Path(__file__).resolve().parent.parent to go two levels up. You can chain .parent as many times as needed.

Why does os.getcwd() return a different path than expected?

os.getcwd() reflects the working directory of the terminal session that launched Python, not the script's location. IDEs often set this to the project root automatically, which works locally but breaks when you deploy to a server or run the script from a cron job in a different folder.

Something wrong or out of date?

Tools change fast. Tell the editor what no longer works.