Python
Relative Paths
File Handling
Programming
Duplicate

Relative paths in Python

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Relative paths in Python are simple until the current working directory is not what you expected. That mismatch is the source of most bugs: the script works from one terminal location, then fails in tests, cron jobs, IDEs, or containers. The fix is to understand what a relative path is relative to, and to choose between working-directory-based paths and file-location-based paths deliberately.

Relative Path Versus Absolute Path

A relative path is interpreted from the current working directory, often shortened to CWD. An absolute path starts at the filesystem root and points to one exact location.

Example:

python
1from pathlib import Path
2
3print(Path.cwd())
4print(Path("data/example.txt"))
5print(Path("data/example.txt").resolve())

If the CWD changes, Path("data/example.txt") points somewhere else. That is why relative paths can be convenient in one environment and dangerous in another.

The Most Important Distinction: CWD Is Not Script Directory

Many developers assume a relative path is resolved from the folder containing the Python file. That is false unless the current process was started from that same folder.

This script prints both locations:

python
1from pathlib import Path
2
3script_dir = Path(__file__).resolve().parent
4cwd = Path.cwd()
5
6print("Script directory:", script_dir)
7print("Current working directory:", cwd)

Those paths are often different.

If your program depends on files that live next to the script itself, build paths from __file__, not from Path.cwd().

Building Paths Relative to the Script File

This is the safest pattern when your package ships templates, config files, or sample data alongside the source code:

python
1from pathlib import Path
2
3BASE_DIR = Path(__file__).resolve().parent
4config_path = BASE_DIR / "config" / "settings.json"
5
6print(config_path)

This works no matter where the program was launched from, as long as the expected file exists beside the code.

When Working Directory Relative Paths Are Correct

Sometimes the CWD really is the right reference point. Command-line tools often use the directory from which the user invoked them because that matches user intent.

python
1from pathlib import Path
2
3report_path = Path("reports/output.txt")
4report_path.parent.mkdir(parents=True, exist_ok=True)
5report_path.write_text("done\\n", encoding="utf-8")
6print(report_path.resolve())

This is appropriate when the tool should create output in the user's current project directory rather than near the installed script.

Prefer pathlib Over Manual String Joining

Older code often uses os.path.join, which still works, but pathlib is cleaner and easier to read:

python
1from pathlib import Path
2
3base = Path(__file__).resolve().parent
4data_file = base / "data" / "input.csv"
5print(data_file)

pathlib also makes it harder to accidentally create malformed paths through manual string concatenation.

Debugging Path Bugs Quickly

When a file "does not exist" but you think it should, print both the CWD and the fully resolved target path.

python
1from pathlib import Path
2
3target = Path("data/input.csv")
4print("cwd:", Path.cwd())
5print("target:", target.resolve())
6print("exists:", target.exists())

That usually reveals the real issue within seconds.

A Practical Rule of Thumb

Use paths relative to __file__ when:

  • the data is part of your code distribution
  • the program should behave the same no matter where it is launched from

Use paths relative to the CWD when:

  • the user intentionally runs the tool inside a project folder
  • output should land where the command was invoked

Choosing one model explicitly is much better than accidentally mixing both in the same module.

Common Pitfalls

  • Assuming relative paths are resolved from the Python file location.
  • Mixing CWD-based and __file__-based paths in the same workflow without a clear rule.
  • Concatenating raw strings instead of using pathlib or os.path.
  • Testing only from one terminal location and missing failures in CI or IDE execution.
  • Calling .resolve() and assuming it proves the file exists; it only computes a normalized absolute path.

Summary

  • Relative paths are resolved from the current working directory, not automatically from the script directory.
  • Use __file__ and pathlib.Path when files live alongside your code.
  • Use CWD-relative paths when command-line behavior should follow the user’s launch location.
  • Print Path.cwd() and the resolved target path to debug path issues quickly.
  • Most path bugs come from ambiguous assumptions about which directory is the reference point.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.