How to Check if a File Exists in Python

What you’ll build or solve

You’ll check whether a file exists before you read, write, or delete it.

When this approach works best

Checking if a file exists works well when you:

  • Validate an input file before reading it, like data.json or a CSV export.
  • Skip work when an output file already exists, like a cached API response or a generated report.
  • Clean up files safely, like deleting old logs only if they’re there.

Skip this approach if you can rely on error handling instead. Catching FileNotFoundError can be simpler than checking first, especially in code that runs in parallel.

Prerequisites

  • Python 3 installed
  • You can run a Python script
  • You know what a file path is, relative vs absolute

Step-by-step instructions

1) Check a path with pathlib

pathlib is the most readable way to work with paths. Use .exists() to see if a path exists at all.

from pathlib import Path

path = Path("data.json")

if path.exists():
    print("Path exists")
else:
    print("Path is missing")

What to look for: .exists() returns True for both files and folders. Step 2 shows how to check for a file specifically.


2) Confirm it’s a file, not a folder

If you need a real file, use .is_file().

from pathlib import Path

path = Path("data.json")

if path.is_file():
    print("File exists")
else:
    print("Missing file, or path is a folder")

If you expect a folder instead, use .is_dir():

from pathlib import Path

path = Path("logs")

if path.is_dir():
    print("Folder exists")

What to look for: .is_file() returns False if the path doesn’t exist, so you usually don’t need a separate .exists() call.


3) Handle missing files without checking first

Sometimes you don’t need an existence check at all. Open the file and handle the error in one place.

Option A: Catch FileNotFoundError

try:
    with open("data.json", "r", encoding="utf-8") as f:
        text = f.read()
except FileNotFoundError:
    text = None

Option B: Test first, then open

Useful when you want branching logic.

from pathlib import Path

path = Path("data.json")

if path.is_file():
    text = path.read_text(encoding="utf-8")
else:
    text = None

What to look for: Error handling avoids a check-then-use gap, which matters if another process can delete the file between your check and your open.


Examples you can copy

Example 1: Read a file only if it exists

from pathlib import Path

path = Path("notes.txt")

if path.is_file():
    content = path.read_text(encoding="utf-8")
else:
    content = ""

Example 2: Create a file only if it’s missing

from pathlib import Path

path = Path("config.json")

if not path.exists():
    path.write_text('{\n  "debug": false\n}\n', encoding="utf-8")

Example 3: Pick a fallback file if the main one is missing

from pathlib import Path

primary = Path("data.json")
fallback = Path("data.sample.json")

path = primary if primary.is_file() else fallback

data_text = path.read_text(encoding="utf-8")

Example 4: Check a file in the script’s folder

This helps when your working folder changes depending on how you run the script.

from pathlib import Path

base = Path(__file__).parent
path = base / "data.json"

print(path.is_file())

Example 5: Check with os.path.exists() as an alternative

Some codebases use os.path instead of pathlib.

import os

if os.path.exists("data.json"):
    print("Exists")

If you need file-only behavior:

import os

if os.path.isfile("data.json"):
    print("File exists")

Common mistakes and how to fix them

Mistake 1: Using .exists() when you need a file

What you might do:

from pathlib import Path

if Path("logs").exists():
    print("Ready to read logs")

Why it breaks: .exists() returns True for folders too, so your code may treat a directory like a file.

Correct approach:

from pathlib import Path

if Path("logs").is_file():
    print("This is a file")
else:
    print("Not a file")

Mistake 2: Checking first, then opening, and still crashing

What you might do:

from pathlib import Path

path = Path("data.json")

if path.is_file():
    text = path.read_text(encoding="utf-8")

Why it breaks: Another process can delete the file after the check. This is a race condition because the file’s state can change between check and use.

Correct approach:

from pathlib import Path

path = Path("data.json")

try:
    text = path.read_text(encoding="utf-8")
except FileNotFoundError:
    text = None

Troubleshooting

If you see FileNotFoundError even after checking, wrap the read or open in try/except because files can disappear between steps.

If .is_file() returns False but the file exists, print the resolved path to confirm you’re checking the right location:

from pathlib import Path
print(Path("data.json").resolve())

If your script behaves differently in an IDE vs terminal, anchor the path to the script folder with Path(__file__).parent.

If you see PermissionError, you may not have access to the folder, or the file may be locked by another app.


Quick recap

  • Use Path(...).exists() to check if a path exists at all.
  • Use Path(...).is_file() when you specifically need a file.
  • Use Path(...).is_dir() when you specifically need a folder.
  • Prefer try/except FileNotFoundError when the file might disappear between check and use.
  • Print Path(...).resolve() if you suspect you’re checking the wrong location.