Call os.getcwd() to get the current directory in Python. It returns the working directory as a string, and Path.cwd() from pathlib gives you the same folder as a Path object:
import os
from pathlib import Path
print(os.getcwd()) # C:\pyguides\runs\cwd
print(Path.cwd()) # C:\pyguides\runs\cwd
One catch trips up almost everyone: that’s the folder you launched Python from, not the folder your script sits in. I’ll show both, with real runs on Python 3.14.7 in Command Prompt.

__file__ is where the script lives.Get the current directory in Python with os.getcwd()
Both ways side by side, plus what each one hands back:
import os
from pathlib import Path
print("os.getcwd():", os.getcwd())
print("Path.cwd(): ", Path.cwd())
print()
print("os.getcwd() returns a", type(os.getcwd()).__name__)
print("Path.cwd() returns a", type(Path.cwd()).__name__)
print("same folder?", str(Path.cwd()) == os.getcwd())
Output:
os.getcwd(): C:\pyguides\runs\cwd
Path.cwd(): C:\pyguides\runs\cwd
os.getcwd() returns a str
Path.cwd() returns a WindowsPath
same folder? True

os.getcwd() gives a string, Path.cwd() gives a Path, and they point at the same folder.os.getcwd() has been around forever and returns a plain str. It’s the one you’ll see in older code and in most Stack Overflow answers.
The name means “get current working directory”. There’s also os.getcwdb(), which returns bytes, but you’ll rarely need it.
My screenshots are from Windows. On a Mac or Linux machine the same code prints a path like /Users/ava/projects/reports with forward slashes, and only the wording of error messages differs.
Get the current working directory with pathlib: Path.cwd()
Path.cwd() returns the same folder as a WindowsPath on Windows, or a PosixPath on Linux and macOS. The output above shows str(Path.cwd()) == os.getcwd() is True.
The difference is what you can do next. A Path has .name, .parent, .glob() and the / operator for joining, so you rarely need os.path again.
That’s why I use Path.cwd() in new code, and only reach for os.getcwd() when a library wants a plain string.
Print the current directory in Python
Printing it is just print() around either call. A few forms you’ll actually use:
import os
from pathlib import Path
print(os.getcwd())
print(f"Working in: {Path.cwd()}")
print(repr(Path.cwd())) # what the REPL shows if you skip print()
print(Path.cwd().as_posix()) # forward slashes, handy for logs
Output:
C:\pyguides\runs\cwd
Working in: C:\pyguides\runs\cwd
WindowsPath('C:/pyguides/runs/cwd')
C:/pyguides/runs/cwd
Notice the third line. If you type Path.cwd() in the REPL without print(), you get the WindowsPath(...) repr with forward slashes, which looks wrong but isn’t.
.as_posix() gives forward slashes on purpose. It’s handy for log files and anything you’ll paste into a URL.
If you came from a Linux shell, os.getcwd() is Python’s pwd. In Command Prompt, typing cd on its own prints the same thing.
Print the current directory from the command line
You don’t need a script file for a quick check. python -c runs one line and exits:
python -c "import os; print(os.getcwd())"
Output:
C:\pyguides\runs\cwd
It’s the quickest way to confirm which folder a batch file or scheduled task really starts Python in.
Why the current working directory isn’t your script’s folder
This is the question behind most searches for this topic. Here’s a script in a scripts folder, run from the folder above it:
import os
from pathlib import Path
print("working directory:", os.getcwd())
print("script folder: ", Path(__file__).parent)
print()
try:
open("config.txt")
except FileNotFoundError as err:
print("open('config.txt') ->", err)
config = Path(__file__).parent / "config.txt"
print("next to the script ->", config.read_text().strip())
Output:
working directory: C:\pyguides\runs\cwd
script folder: C:\pyguides\runs\cwd\scripts
open('config.txt') -> [Errno 2] No such file or directory: 'config.txt'
next to the script -> theme=dark

open("config.txt") looks in the wrong place. The script’s own folder finds it.os.getcwd() reports the folder I ran python from, while Path(__file__).parent reports where where.py actually lives. They’re different folders.
That’s why the plain open("config.txt") fails. A relative path is always resolved against the working directory, and the file isn’t there.
The fix is to build the path from __file__, as the last line does. Now the script finds its file no matter where it’s launched from.
One detail surprised me when I tested this: __file__ is already an absolute path, even though I typed a relative one. sys.argv[0], on the other hand, stays exactly as typed.
In the REPL or with python -c, __file__ doesn’t exist at all: NameError: name '__file__' is not defined. There’s more on this in getting the path of the current file.
IDEs add their own twist, because the run button often starts Python from the project folder. When a relative path misbehaves, print os.getcwd() first.
Make a script work from any folder
The usual pattern is a BASE_DIR constant at the top of the script. Here it’s launched from two folders up, and it still finds its file:
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent
config = BASE_DIR / "config.txt"
print("launched from:", Path.cwd())
print("reading: ", config)
print("contents: ", config.read_text().strip())
Output:
launched from: C:\pyguides\runs
reading: C:\pyguides\runs\cwd\scripts\config.txt
contents: theme=dark
.resolve() turns the path into a clean absolute one, and every file the script needs is built from BASE_DIR. Django’s settings file uses exactly this idea.
Once you do this, the working directory stops mattering for your own files. It only matters for paths the user types in.
Get the current folder name in Python
Sometimes you only want the last part, like cwd rather than the full path:
import os
from pathlib import Path
print("Path.cwd().name: ", Path.cwd().name)
print("os.path.basename(getcwd()): ", os.path.basename(os.getcwd()))
print()
print("with a trailing backslash:")
print(' os.path.basename("C:\\data\\") ->', repr(os.path.basename("C:\\data\\")))
print(' Path("C:\\data\\").name ->', repr(Path("C:\\data\\").name))
print()
print('at a drive root, Path("C:/").name ->', repr(Path("C:/").name))
Output:
Path.cwd().name: cwd
os.path.basename(getcwd()): cwd
with a trailing backslash:
os.path.basename("C:\data\") -> ''
Path("C:\data\").name -> 'data'
at a drive root, Path("C:/").name -> ''

.name and basename() agree, until there’s a trailing backslash.Path.cwd().name and os.path.basename(os.getcwd()) give the same answer for the working directory, because getcwd() never ends in a separator.
Paths you build yourself might, though. os.path.basename("C:\\data\\") returns an empty string, while Path("C:\\data\\").name still says data.
Need the name of the folder above instead? Chain them: Path.cwd().parent.name gives runs for the folder in these examples.
At a drive root there’s no folder name at all, so you get '' from both. For names of files rather than folders, see getting a filename from a path.
Go up one level: the parent of the current directory
.parent moves up one folder, and .parents gives you every folder above:
import os
from pathlib import Path
here = Path.cwd()
print("current: ", here)
print("one level up: ", here.parent)
print("two levels up:", here.parents[1])
print("os.path way: ", os.path.dirname(os.getcwd()))
print()
print("every level above:")
for folder in here.parents:
print(" ", folder)
Output:
current: C:\pyguides\runs\cwd
one level up: C:\pyguides\runs
two levels up: C:\pyguides
os.path way: C:\pyguides\runs
every level above:
C:\pyguides\runs
C:\pyguides
C:\

.parent is one level up; .parents[1] is two.here.parents[1] is the grandparent, and looping over .parents walks all the way to the drive. os.path.dirname() does the one-level version for strings.
None of this changes the working directory. It just calculates a path, whi