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, which is usually what you want.
For a string-based version of two levels up, you’d nest calls: os.path.dirname(os.path.dirname(os.getcwd())). That’s exactly the kind of line that made me switch to pathlib.
Change the current working directory with os.chdir()
When you really do need to move, os.chdir() does it:
import os, contextlib
print("start: ", os.getcwd())
os.chdir("scripts")
print("after chdir:", os.getcwd())
os.chdir("..")
print("back again: ", os.getcwd())
print()
with contextlib.chdir("scripts"):
print("inside with:", os.getcwd())
print("after with: ", os.getcwd())
print()
for target in ("no_such_folder", "scripts/config.txt"):
try:
os.chdir(target)
except OSError as err:
print(type(err).__name__, "->", err)
Output:
start: C:\pyguides\runs\cwd
after chdir: C:\pyguides\runs\cwd\scripts
back again: C:\pyguides\runs\cwd
inside with: C:\pyguides\runs\cwd\scripts
after with: C:\pyguides\runs\cwd
FileNotFoundError -> [WinError 2] The system cannot find the file specified: 'no_such_folder'
NotADirectoryError -> [WinError 267] The directory name is invalid: 'scripts/config.txt'

contextlib.chdir puts you back automatically. A missing folder or a file raises an error.os.chdir() changes the directory for the whole process, not just the current function. That’s easy to forget, and it can break other code that relied on relative paths.
contextlib.chdir is the safer version. It changes directory inside the with block and restores the old one afterwards, even if an exception is raised.
It arrived in Python 3.11. I checked: it’s missing on 3.10.11 and present on 3.11 and later.
The two errors are worth recognizing. A missing folder raises FileNotFoundError with WinError 2, and pointing at a file raises NotADirectoryError with WinError 267.
Build file paths from the current directory
If you searched for the “current path” in Python, this is usually what you were after. The directory on its own is rarely the goal; a full path to a file inside it is.
Most of the time you want the directory so you can put a file name on the end:
import os
from pathlib import Path
report = Path.cwd() / "reports" / "2026-09-sales.csv"
print(report)
print("name: ", report.name)
print("suffix:", report.suffix)
print()
print(os.path.join(os.getcwd(), "reports", "2026-09-sales.csv"))
print(os.path.abspath("notes.txt")) # a relative name resolves against the working directory
Output:
C:\pyguides\runs\cwd\reports\2026-09-sales.csv
name: 2026-09-sales.csv
suffix: .csv
C:\pyguides\runs\cwd\reports\2026-09-sales.csv
C:\pyguides\runs\cwd\notes.txt
With pathlib, the / operator joins parts and picks the right separator for you. .name and .suffix pull pieces back out.
os.path.abspath() shows how Python sees a relative name: it’s glued onto the working directory. Before opening, checking that the file exists saves you a traceback.
pathlib has two ways to make a relative path absolute, and they don’t do the same thing:
from pathlib import Path
p = Path("reports/../data.csv")
print("as written: ", p)
print(".absolute(): ", p.absolute())
print(".resolve(): ", p.resolve())
Output:
as written: reports\..\data.csv
.absolute(): C:\pyguides\runs\cwd\reports\..\data.csv
.resolve(): C:\pyguides\runs\cwd\data.csv
.absolute() only sticks the working directory on the front, so the .. stays in. .resolve() also cleans it up and follows links, which is what you want before comparing two paths.
List the files in the current directory
Once you know where you are, listing what’s there is one line:
import os
from pathlib import Path
data = Path.cwd() / "data"
data.mkdir(exist_ok=True)
for name in ("sales.csv", "costs.csv", "notes.txt"):
(data / name).write_text("x")
os.chdir(data)
print("os.listdir(): ", sorted(os.listdir()))
print("only .csv files:", sorted(p.name for p in Path.cwd().glob("*.csv")))
print("files only: ", sorted(p.name for p in Path.cwd().iterdir() if p.is_file()))
Output:
os.listdir(): ['costs.csv', 'notes.txt', 'sales.csv']
only .csv files: ['costs.csv', 'sales.csv']
files only: ['costs.csv', 'notes.txt', 'sales.csv']
os.listdir() returns names in no guaranteed order, which is why I sort them. glob("*.csv") filters by pattern, and is_file() skips folders.
Walking subfolders and filtering by extension are covered in listing files in a directory with Python.
Common current directory mistakes in Python
Most of the bugs I see around the working directory fall into a handful of patterns:
- Opening a data file with a bare name like
open("config.txt"), then running the script from somewhere else. - Calling
os.getcwd()inside an imported module and expecting the module’s folder. It still reports where Python was launched. - Calling
os.chdir()in a helper and forgetting it changes the directory for the whole program. - Using
os.path.basename()on a path that ends in a backslash and getting an empty string back. - Reaching for
__file__in the REPL or withpython -c, where it doesn’t exist.
All five have the same cure: decide whether you mean “where I ran it” or “where the file lives”, and use the matching call.
os.getcwd() or Path.cwd(): which should you use?
| You want | Use | Returns |
|---|---|---|
| The current directory as text | os.getcwd() | str |
| The current directory to build paths from | Path.cwd() | Path |
| Just the folder name | Path.cwd().name | str |
| One level up | Path.cwd().parent | Path |
| The script’s own folder | Path(__file__).parent | Path |
| Change directory for a block | contextlib.chdir(...) | context manager |
For a quick script or a one-off check, os.getcwd() is perfectly fine. The moment you start joining folder names or reading several files, Path.cwd() keeps the code shorter and easier to read.
If you remember one row, make it the script’s-folder one. Most “file not found” bugs I’ve debugged in scripts come from using the working directory when the script’s own folder was meant.
These go well with working-directory code:
- Get the directory of a file
- Import a Python file from the same directory
- Get a file extension from a file name
- Read a file line by line
Frequently asked questions
How do I get the current directory in Python?
Call os.getcwd(), which returns the working directory as a string. Path.cwd() from pathlib returns the same folder as a Path object.
What is the difference between os.getcwd() and Path.cwd()?
They point at the same folder. os.getcwd() returns a str, and Path.cwd() returns a Path with .name, .parent and / joining built in.
Why is os.getcwd() different from my script’s folder?
The working directory is where you started Python, not where the file is saved. Use Path(__file__).parent for the script’s folder.
How do I get only the current folder name?
Use Path.cwd().name or os.path.basename(os.getcwd()). For paths with a trailing backslash, .name is safer because basename() returns an empty string.
How do I change the current working directory in Python?
Call os.chdir(path). On Python 3.11 and later, with contextlib.chdir(path): changes it for one block and restores the old directory afterwards.
How do I go up one directory in Python?
Use Path.cwd().parent, or os.path.dirname(os.getcwd()) for a string. Neither changes the working directory; call os.chdir() on the result if you need to move.
Is there a pwd command in Python?
Not as a command, but os.getcwd() does the same job and is what pwd maps to. It’s documented with the other directory functions in the Python os module reference.
Bijay Kumar is a 13-time Microsoft MVP with more than 18 years in software development, and the founder of Python Guides and TSinfo Technologies. He started out building .NET and SharePoint solutions at HP, TCS and KPIT before moving into Python, machine learning and AI, and he also builds web apps with TypeScript and React. He writes the tutorials here himself, and every example is run before publishing so you see the real output. More about Bijay · Microsoft MVP profile · LinkedIn