The ability to check whether a file exists on disk or not is important for many types of Python programs:
Maybe you want to make sure a data file is available before you try to load it, or maybe you want to prevent overwriting an existing file. The same is true for directories—maybe you need to ensure an output folder is available before your program runs.
In Python, there are several ways to verify a file or directory exists using functions built into the core language and the Python standard library.
In this tutorial you’ll see three different techniques for file existence checks in Python, with code examples and their individual pros and cons.
Let’s take a look!
These functions are available on Python 2 and 3, and they’re usually the first suggestion that comes up when you consult the Python docs or a search engine on how to solve this problem.
Here’s a demo of how to work with the
os.path.exists() function. I’m checking several paths (files and directories) for existence in the example below:
>>> import os.path >>> os.path.exists('mydirectory/myfile.txt') True >>> os.path.exists('does-not-exist.txt') False >>> os.path.exists('mydirectory') True
As you just saw, calling
os.path.exists() will return
True for files and directories. If you want to ensure that a given path points to a file and not to a directory, you can use the
>>> import os.path >>> os.path.isfile('mydirectory/myfile.txt') True >>> os.path.isfile('does-not-exist.txt') False >>> os.path.isfile('mydirectory') False
With both functions it’s important to keep in mind that they will only check if a file exists—and not if the program actually has access to it. If verifying access is important then you should consider simply opening the file while looking out for an I/O exception (
IOError) to be raised.
We’ll come back to this technique in the summary at the end of the tutorial. But before we do that, let’s take a look at another option for doing file existence checks in Python.
You just saw how functions in the
os.path module can be used to check for the existence of a file or a folder.
Here’s another straightforward Python algorithm for checking whether a file exists: You simply attempt to open the file with the built-in
open() function, like so:
>>> open('does-not-exist.txt') FileNotFoundError: "[Errno 2] No such file or directory: 'does-not-exist.txt'"
If the file exists the
open call will complete successfully and return a valid file handle. If the file does not exist however, a
FileNotFoundError exception will be raised:
FileNotFoundErroris raised when a file or directory is requested but doesn’t exist. Corresponds to errno ENOENT.” (Source: Python Docs)
This means you can watch for this
FileNotFoundError exception type in your own code, and use it to detect whether a file exists or not. Here’s a code example that demonstrates this technique:
try: f = open('myfile.txt') f.close() except FileNotFoundError: print('File does not exist')
Notice how I’m immediately calling the
close() method on the file object to release the underlying file handle. This is generally considered a good practice when working with files in Python:
If you don’t close the file handle explicitly it is difficult to know when exactly it will be closed automatically by the Python runtime. This wastes system resources and can make your programs run less efficiently.
Instead of closing the file explicitly with the
close() method, another option here would be to use the context manager protocol and the
with statement to auto-close the file.
Now, the same “just attempt to open it” technique also works for ensuring a file is both readable and accessible. Instead of watching for
FileNotFoundError exceptions you’ll want to look out for any kind of
try: f = open('myfile.txt') f.close() except IOError: print('File is not accessible') print('File is accessible')
If you frequently use this pattern you can factor it out into a helper function that will allow you to test whether a file exists and is accessible at the same time:
def is_accessible(path, mode='r'): """ Check if the file or directory at `path` can be accessed by the program using `mode` open flags. """ try: f = open(path, mode) f.close() except IOError: return False return True
Alternatively, you can use the
os.access() function in the standard library to check whether a file exists and is accessible at the same time. This would be more similar to using the
os.path.exists() function for checking if a file exists.
open() and a
try...except clause has some advantages when it comes to file handling in Python. It can help you avoid bugs caused by file existence race conditions:
Imagine a file exists in the instant you run the check, only to get removed a millisecond later. When you actually want to open the file to work with it, it’s gone and your program aborts with an error.
I’ll cover this edge case in some more detail in the summary below. But before we get down another rabbit hole—let’s take a look at one more option for checking if a file or folder exists in Python.
pathlib.Path.exists() (Python 3.4+)
Python 3.4 and above include the
pathlib module that provides an object-oriented interface for dealing with file system paths. Using this module is much nicer than treating file paths as simple string objects.
It provides abstractions and helper functions for many file system operations, including existence checks and finding out whether a path points to a file or a directory.
To check whether a path points to a valid file you can use the
Path.exists() method. To find out whether a path is a file or a symbolic link, instead of a directory, you’ll want to use
Here’s a working example for both
>>> import pathlib >>> path = pathlib.Path('myfile.txt') >>> path.exists() True >>> path.is_file() True
As you can tell, this approach is very similar to doing an existence check with functions from the
The key difference is that
pathlib provides a cleaner object-oriented interface for working with the file system. You’re no longer dealing with plain
str objects representing file paths—but instead you’re handling
Path objects with relevant methods and attributes on them.
pathlib and taking advantage of its object-oriented interface can make your file handling code more readable and more maintainable. I’m not going to lie to you and say this is a panacea. But in some cases it can help you write “better” Python programs.
pathlib module is also available as a backported third-party module on PyPI that works on Python 2.x and 3.x. You can find it here:
Summary: Checking if a File Exists in Python
In this tutorial we compared three different methods for determining whether a file exists in Python. One method also allowed us to check if a file exists and is accessible at the same time.
Of course, with three implementations to choose from you might be wondering:
What’s the preferred way to check if a file exists using Python?
In most cases where you need a file existence check I’d recommend you use the built-in
pathlib.Path.exists() method on Python 3.4 and above, or the
os.path.exists() function on Python 2.
However, there’s one important caveat to consider:
Keep in mind that just because a file existed when the check ran won’t guarantee that it will still be there when you’re ready to open it:
While unlikely under normal circumstances, it’s entirely possible for a file to exist in the instant the existence check runs, only to get deleted immediately afterwards.
To avoid this type of race condition, it helps to not only rely on a “Does this file exist?” check. Instead it’s usually better to simply attempt to carry out the desired operation right away. This is also called an “easier to ask for forgiveness than permission” (EAFP) style that’s usually recommended in Python.
For example, instead of checking first if a file exists before opening it, you’ll want to simply try to open it right away and be prepared to catch a
FileNotFoundError exception that tells you the file wasn’t available. This avoids the race condition.
So, if you plan on working with a file immediately afterwards, for example by reading its contents or by appending new data to it, I would recommend that you do the existence check via the
open() method and exception handling in an EAFP style. This will help you avoid race conditions in your Python file handling code.
If you’d like to dig deeper into the subject, be sure to watch my YouTube tutorial on file existence checks in Python. It’s also embedded at the top of the article. Happy Pythoning!