We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.

Check If a File Exists in Python: pathlib and os.path

Lane Wagner
Lane WagnerBoot.dev co-founder and backend engineer

Last published

Table of Contents

When I need to check whether a file exists in Python, it's as easy as creating a Path object and calling is_file():

from pathlib import Path

file_path = Path("data/report.csv")

if file_path.is_file():
    print("The file exists")
else:
    print("The file does not exist")

I use is_file() when I specifically need a file. I use exists() when either a file or a directory should count.

Checking if a path exists

The pathlib module, added in Python 3.4, represents a filesystem path as an object and gives you methods for inspecting or changing that path.

When I only care whether something exists at a path, I call Path.exists():

from pathlib import Path

path = Path("data/report.csv")

if path.exists():
    print("Something exists at this path")

exists() returns True when the path points to an existing filesystem entry. A missing path returns False.

The exists(), is_file(), and is_dir() methods live on a Path object, so the object comes first: Path("data/report.csv").exists().

Path.exists() vs. Path.is_file()

You can just pick the method based on what your program expects to find:

Check Method Returns True When
Any existing path path.exists() The path is a file, directory, or other item
A regular file path.is_file() The path points to a file
A directory path.is_dir() The path points to a directory
A symbolic link path.is_symlink() The path itself is a symbolic link

is_file() and is_dir() follow symlinks, so a symlink to a regular file can make both is_file() and is_symlink() return True.

Here, exists() and is_file() return different results for a directory:

from pathlib import Path

path = Path("data")

print(path.exists())   # True if data exists as a file or directory
print(path.is_file())  # True only if data is a regular file
print(path.is_dir())   # True only if data is a directory

If your next step is opening data/report.csv as a file, is_file() makes that restriction clearer than exists().

When your code needs a directory, you can use is_dir():

from pathlib import Path

upload_dir = Path("uploads")

if upload_dir.is_dir():
    print("The upload directory exists")

When you need to know whether the path itself is a symbolic link, you can use is_symlink():

from pathlib import Path

latest_report = Path("reports/latest.csv")

if latest_report.is_symlink():
    print("The report path is a symlink")

A broken symlink can return False from exists() because its target is missing while still returning True from is_symlink().

Checking with os.path.exists()

You'll still see os.path.exists() in older code. It accepts a string or path-like object and, like Path.exists(), returns True for both files and directories:

import os

if os.path.exists("data/report.csv"):
    print("The path exists")

If you're working with os.path and only a file should count, you can use os.path.isfile():

import os

if os.path.isfile("data/report.csv"):
    print("The file exists")

os.path still works, but I find pathlib easier to read and compose. Joining a directory and filename becomes Path("data") / "report.csv" instead of os.path.join("data", "report.csv").

Opening a file without checking first

If I'm about to open the file anyway, I usually skip the separate existence check and catch FileNotFoundError:

from pathlib import Path

file_path = Path("data/report.csv")

try:
    contents = file_path.read_text(encoding="utf-8")
except FileNotFoundError:
    print("The report does not exist")
else:
    print(contents)

A separate check would leave a race between checking and opening. Another process could delete or move the file after is_file() returns True but before your program opens it.

An existence check does not prove that you can read or write the file. Permissions and other filesystem errors can still make the operation fail, so you'll still need to handle the errors the operation itself can raise.

Checking a file in the current directory

Python resolves relative paths from the program's current working directory. That isn't always the directory containing your Python script:

from pathlib import Path

print(Path.cwd())
print(Path("settings.json").is_file())

When a file lives next to your script, you can build the path from __file__ instead:

from pathlib import Path

script_dir = Path(__file__).resolve().parent
settings_path = script_dir / "settings.json"

if settings_path.is_file():
    print("Found settings.json next to the script")

Now the result won't change just because you launched the script from another directory.

Creating a file if it does not exist

When I want to create an empty file only if it's missing, I use Path.touch(). Its default exist_ok=True leaves an existing file in place, although it can update that file's modification time:

from pathlib import Path

log_path = Path("logs/app.log")
log_path.parent.mkdir(parents=True, exist_ok=True)
log_path.touch(exist_ok=True)

The parent directory may be missing too, which is why the example creates it first with mkdir(parents=True, exist_ok=True).

My rule of thumb is Path.is_file() for a file, Path.exists() for any kind of path, and try/except FileNotFoundError when I'm about to open the file anyway. If you want to get more comfortable with paths, exceptions, and the rest of Python's fundamentals, work through Learn Python for Beginners.

Frequently Asked Questions

What is the best way to check if a file exists in Python?

Path.is_file() is my default when I specifically need a file, as in Path('report.csv').is_file(). I use exists() when either a file or directory should count.

What is the difference between Path.exists() and Path.is_file()?

Path.exists() returns True for any existing filesystem path, including files and directories. Path.is_file() returns True only when the path points to a regular file.

Does os.path.exists() check for both files and directories?

Yes. os.path.exists() returns True for either an existing file or directory. I use os.path.isfile() when only a regular file should return True.

Should I check if a file exists before opening it?

Not always. If I'm about to open the file anyway, I catch FileNotFoundError and avoid a race between the existence check and the open operation.

Why does Python say a file does not exist when it does?

A relative path is resolved from the program's current working directory, not necessarily the script's directory. You can print Path.cwd() to inspect it or build a path relative to Path(__file__).resolve().parent.