Python Get Current Directory: os.getcwd() and Path.cwd()

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.

Diagram showing the Python current working directory compared with the folder that holds the script
The working directory is where you ran Python. __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
Command Prompt showing Python os.getcwd and Path.cwd returning the current working directory
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
Command Prompt showing a Python script where the working directory differs from the script folder and open raises FileNotFoundError
Run from the parent folder, 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 -> ''
Command Prompt showing Python getting the current folder name with pathlib name and os.path.basename
.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:\
Command Prompt showing Python Path parent and parents to go up from the current working directory
.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'
Command Prompt showing Python os.chdir changing the working directory and contextlib.chdir restoring it
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 with python -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 wantUseReturns
The current directory as textos.getcwd()str
The current directory to build paths fromPath.cwd()Path
Just the folder namePath.cwd().namestr
One level upPath.cwd().parentPath
The script’s own folderPath(__file__).parentPath
Change directory for a blockcontextlib.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:

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.