Quick answer: Use os.getcwd() or Path.cwd() to read the current working directory in Python. It is the directory used to resolve relative paths, which may be different from the directory containing your Python file.

Python’s current working directory belongs to the running process. It is the folder Python uses when code opens a relative path such as data/input.csv. The value depends on how the program was launched, the terminal location, the test runner, or an earlier call to os.chdir().
The official os.getcwd() documentation and Path.cwd() documentation describe the two common interfaces. Use pathlib for most new path-building code, while os.getcwd() remains perfectly valid when an existing API expects a string.
Use os.getcwd()
os.getcwd() returns the current working directory as a string.
import os
working_directory = os.getcwd()
print(working_directory)
The returned value is normally absolute. It tells you where relative file operations start, not where the source file is stored. A command launched from a different terminal directory can therefore produce a different result.
Use pathlib Path.cwd()
Path.cwd() returns the current directory as a Path object. This is convenient when the result will be joined to another path.
from pathlib import Path
base = Path.cwd()
input_file = base / "data" / "input.csv"
print(base)
print(input_file)
The slash operator builds a path using the platform’s path rules. It is easier to read than manually joining strings and avoids accidentally mixing separators.
Current Directory Versus Script Directory
The current working directory is not automatically the directory containing the script. To locate a file relative to the script itself, resolve __file__ instead.
from pathlib import Path
script_directory = Path(__file__).resolve().parent
template = script_directory / "templates" / "email.txt"
print(template)
This distinction matters when a script is started from a scheduler, an IDE, a test runner, or another directory. Use the working directory when the user intentionally supplies a project-relative path. Use the script directory when a package-owned resource must travel with the code.
Build Reliable Relative Paths
Read the directory once and construct paths explicitly. Avoid concatenating strings with a hard-coded slash.
from pathlib import Path
project = Path.cwd()
output_directory = project / "output"
output_directory.mkdir(parents=True, exist_ok=True)
report = output_directory / "summary.txt"
report.write_text("complete\n", encoding="utf-8")
Creating a directory before writing makes the file operation’s assumptions clear. For user-provided paths, validate the path and decide whether it should be relative to the current directory or expanded to an absolute path.
Temporarily Change The Working Directory
os.chdir() changes the working directory for the whole process. Restore it in a finally block if the change is temporary.
import os
from pathlib import Path
previous = Path.cwd()
try:
os.chdir("reports")
print(Path.cwd() / "daily.csv")
finally:
os.chdir(previous)
Changing process-wide state can surprise other code, especially in a web server, notebook, or test suite. Prefer absolute paths or pass a cwd argument to a subprocess when that is enough.
Inspect Files From The Current Directory
Path.iterdir() and Path.glob() provide readable ways to inspect entries.
from pathlib import Path
for path in sorted(Path.cwd().glob("*.csv")):
if path.is_file():
print(path.name)
Use is_file() when directories should not be treated as input files. For recursive searches, use rglob(), but be deliberate about performance and hidden or generated directories.
Common Mistakes
Printing os.getcwd() can diagnose a missing-file error, but it does not fix an incorrect path contract. Do not assume the terminal folder equals the script folder. Do not call os.chdir() globally just to make one file open successfully. Also avoid embedding a developer’s absolute path in code that must run on another machine.
For tests, create a temporary directory and pass paths explicitly. That keeps the test independent of the directory from which the test command happens to run.
For a related path operation, see looping through files in a Python directory and removing directories with shutil.
Resolve And Compare Paths
A path can be relative even when it came from a user or configuration file. Use Path.resolve() when you need to compare locations or display an absolute diagnostic path.
from pathlib import Path
candidate = Path("data") / "input.csv"
absolute = candidate.resolve()
print(candidate)
print(absolute)
Resolution can consult the filesystem depending on the platform and options, so do not use it as a substitute for checking whether a file should be trusted. A resolved path is useful for diagnostics; permissions and application-specific validation still matter.
Pass A Working Directory To A Subprocess
When only a child command needs a different directory, pass it to the subprocess instead of changing the parent process.
from pathlib import Path
import subprocess
project = Path.cwd() / "project"
subprocess.run(["python", "build.py"], cwd=project, check=True)
This keeps the Python process stable and makes the child command’s assumptions visible at the call site. It is especially useful for test runners and build tools that may run concurrently.
Debug A Missing File
When a relative file cannot be opened, print the current directory, the path you constructed, and whether the parent exists.
from pathlib import Path
path = Path("data") / "input.csv"
print({
"cwd": str(Path.cwd()),
"path": str(path),
"absolute": str(path.absolute()),
"parent_exists": path.parent.exists(),
})
This produces useful evidence without changing global state. Once the path contract is corrected, remove verbose diagnostics or route them through a logger at an appropriate level.
Remember that relative paths are evaluated at the moment the operation runs. A function that accepts a filename should document whether it expects a path relative to the caller’s current directory, a project root, or a directory chosen by configuration. Hidden assumptions are a common reason code works from an IDE but fails from a scheduled job.
For reusable libraries, accept a PathLike value or a Path and avoid changing the process directory internally. A caller can then decide the correct base directory, while the library remains safe to use beside other code.
That small boundary keeps command-line behavior, tests, and imported library code predictable across operating systems.
Frequently Asked Questions
How do I get the current directory in Python?
Call os.getcwd() to get it as a string or Path.cwd() to get it as a pathlib Path object.
Is the current directory the same as the script directory?
Not necessarily. The current directory depends on how the process was launched, while the script directory can be derived from Path(__file__).resolve().parent.
How do I build a path from the current directory?
Use Path.cwd() and the pathlib slash operator, such as Path.cwd() / ‘data’ / ‘input.csv’, instead of concatenating path strings.
How do I temporarily change the current directory?
Save Path.cwd(), call os.chdir() inside a try block, and restore the previous directory in finally so process-wide state is not left changed.