The Python standard library contains most of the functionality a developer would need to solve a problem. In this tutorial, you’ll learn different ways to check the existence of a file or directory using only built-in modules.
Checking if a file or script is in the correct spot is crucial for any CLI program. Your program could become useless if a specific file isn’t in place at the moment of execution.
In today’s tutorial, you’ll learn some quick ways to check if a file or folder exists in Python.
Before starting
Before executing any command below, make sure you have Python 3 installed in your system. Open your terminal and type the following command:
python --version
# Python 3.9.5, my result
If you got a 2.x version, you’ll need to use the “python3” command. Check out our Python installation guide if you don’t have Python 3 installed.
We’ll be using some test files along with this tutorial, so make sure to create the following files:
touch testfile.txt
mkdir testdirectory/
touch testdirectory/otherfile.txt
The commands above create a file to play with, a testing directory, and another file inside the testingdirectory. The files can be empty since we won’t need to read their content,
Note: If you’re using Windows, set up that file simple file structure with a graphical file manager.
Finally, we’ll be using Ipython as our interactive Python shell which gives a pretty interface to work with. This is just a commodity, therefore not strictly necessary.
pip install ipython
After doing this, you’ll get access to a beautiful Python shell just by typing ipython.
Now you’re all set let’s dive into ways to check if a folder or file exists in Python.
Try, Open, and Except
This is the most straightforward option. If you try to open a file that doesn’t exist, Python will raise a FileNotFoundError.
In [1]: open('im-not-here.txt')
---------------------------------------------------------------------------
FileNotFoundError: [Errno 2] No such file or directory: 'im-not-here.txt'
We can take advantage of this, and handle the exception in case the file we’re looking for doesn’t exist.
In [2]: try:
...: file = open('im-not-here.txt')
...: print(file) # File handler
...: file.close()
...: except FileNotFoundError:
...: print('Sorry the file we\'re looking for doesn\' exist')
...: exit()
...:
Sorry the file we're looking for doesn't exist
In the code above we’re printing a custom message and stopping the execution of the program if the file doesn’t exist.
Note how the exit() function will only execute if an exception is raised. Let’s see what happens when the file we’re looking for actually exists.
In [2]: try:
...: file = open('testfile.txt')
...: print(file) # File handler
...: file.close()
...: except FileNotFoundError:
...: print('Sorry the file we\'re looking for doesn\'t exist')
...: exit()
...:
<_io.TextIOWrapper name='testfile.txt' mode='r' encoding='UTF-8'>
Note how we’re closing the file right after we opened it. It’s considered a good practice according to the Python documentation.
Calling
<span class="pre">file.write()</span>
without using the<span class="pre">with</span>
keyword or calling<span class="pre">file.close()</span>
might result in the arguments of<span class="pre">file.write()</span>
not being completely written to the disk, even if the program exits successfully.
Even if we’re not writing to the file, it’s extremely recommended to close the file because it could lead to multiple performance problems.
If we don’t want to close the file by ourselves, we could use the with context manager. It allocates and releases resources precisely, therefore we won’t need to close the file.
In [3]: try:
...: with open('testfile.txt') as file:
...: print(file)
...: # No need to close the file
...: except FileNotFoundError:
...: print('Sorry the file we\'re looking for doesn\'t exist')
...: exit()
...:
...:
<_io.TextIOWrapper name='testfile.txt' mode='r' encoding='UTF-8'>
This method is extremely useful when writing in files, but results inefficient if we only want to check if a file exists. Let’s dive into other options to achieve this.
os.path.exists()
The os module provides multiple functions to interact with the operative system. To check if a file or folder exists we can use the path.exists() function which accepts the path to the file or directory as an argument. It returns a boolean based on the existence of the path.
Note: A path is the unique location of a file or directory in a filesystem
In Python, the os.path submodule contains functions exclusively designed to operate with file paths. All of these functions accept the path argument as strings or bytes, and you can decide to work with absolute paths, for instance:
/home/daniel/.bashrc
Or with relative paths, depending on the directory you’re running the script:
.bashrc
# Running the script in my home folder
Here are multiple examples using the os.path.exists() function, running in the directory my testing files are located:
In [1]: import os
In [2]: os.path.exists('testfile.txt')
Out[2]: True
In [3]: os.path.exists('testdirectory')
Out[3]: True
In [4]: os.path.exists('hey-i-dont-exist')
Out[4]: False
As you can see, it returns True when testing with the testfile.txt file and the testdirectory folder, and False when the file doesn’t exist.
os.path.isfile()
If you only wanted to prove the existence of a file (not a directory), you would call the os.path.isfile() function.
In [1]: import os
In [2]: os.path.isfile('testfile.txt')
Out[2]: True
In [3]: os.path.isfile('testdirectory/')
Out[3]: False
In [4]: os.path.isfile('i-dont-even-exist')
Out[4]: False
In [5]: os.path.isfile('testdirectory/otherfile.txt')
Out[5]: True
Note: In UNIX all directories end with a forward-slash (/), whereas in Windows we use a backslash (\).
In the code above the isfile() function return False on two occasions, let’s see why:
testdirectory/
is a directory, therefore it is not considered as a file. This isn’t absolutely true since in Linux everything is a file descriptor, but Python treats directories differently just for convenience (If you try to open a directory you’ll get an IsADirectoryError)i-dont-even-exist
is pointing to a file that ironically doesn’t exist
os.path.isdir()
If you want to check a directory is in the correct spot, you’ll need to use the os.path.isdir() function, which only returns True if the given path points to a directory.
In [1]: import os
In [2]: os.path.isdir('testfile.txt')
Out[2]: False
In [3]: os.path.isdir('testdirectory')
Out[3]: True
In [4]: os.path.isdir('anotherfile.txt')
Out[4]: False
Note how the examples above return False even when the path is pointing to a file that exists.
Glob
The glob module provides functions to work with Unix shell-like patterns (hence it doesn’t work properly on Windows). To check if a file matches a pattern inside the current directory, you can use the glob.glob() function.
In [1]: import glob
In [2]: glob.glob('testfile.txt')
Out[2]: ['testfile.txt']
In [3]: glob.glob('testdirectory')
Out[3]: ['testdirectory']
In the code above, the pattern passed to the glob function is a normal string that represents the path to the test file and directory. Since both paths exist, the function returns a list with the matching pathnames inside of it.
Note: If the pattern didn’t match you’d get an empty list.
Considering we can pass patterns to the glob function, why not test out some of the main advantages of it?
The code below gets all the file paths with an extension .txt and .py respectively:
In [4]: glob.glob('*.txt')
Out[4]: ['testfile.txt']
In [5]: glob.glob('*.py')
Out[5]:
['pathlib-exists.py',
'list-dir.py',
'glob-file.py',
'open-except.py',
'subprocess-test.py',
'isfile.py',
'exists.py',
'isdir.py']
Using the Path Class
The Path class is one of the best ways to work with paths since it gives us a clean interface to work with File paths as objects.
The cherry of the cake is that Path instances have all the methods you’d need to get info about a certain path. This includes similar functionalities to the previous options.
Note: You’ll need Python 3.4 or greater to use the pathlib library
The Path methods you’ll use:
Check if a path exists
In [1]: from pathlib import Path
In [2]: Path('testfile.txt').exists()
Out[2]: True
In [3]: Path('im-not-here.txt').exists()
Out[3]: False
In [4]: Path('testdirectory').exists()
Out[4]: True
Works the same as os.path.exists().
Check if the path points to a file
In [5]: Path('testfile.txt').is_file()
Out[5]: True
In [6]: Path('testdirectory').is_file()
Out[6]: False
Equivalent to os.path.isfile().
Check if the path points to a directory
In [7]: Path('testfile.txt').is_dir()
Out[7]: False
In [8]: Path('testdirectory').is_dir()
Out[8]: True
Corresponds to os.path.isdir().
subprocess
If you’re a subprocess module lover, you’ll need to know about this option. You can determine if a file or folder exists by using the test command.
Note: The test command only works in Unix.
The following test flags will get the job done:
- test -e: Check if a path exists
- test -f: Check if a file exists
- test-d: Check if a folder exists
In case you want to dive into more test flags, you can read the manual by running:
man test
Checking a Path with subprocess:
The code below determines if a path exists by comparing the return code of the subprocess to 0.
Remember that in Linux, if a process went well, it’ll return zero, if it didn’t it’ll return any other code.
In [1]: from subprocess import run
In [2]: run(['test', '-e', 'testfile.txt']).returncode == 0
Out[2]: True
In [3]: run(['test', '-e', 'im-not-here.txt']).returncode == 0
Out[3]: False
In the first statement, we’re importing the subprocess module, then using the run function and getting its return code.
Verifying the existence of a file with subprocess
In [4]: run(['test', '-f', 'testfile.txt']).returncode == 0
Out[4]: True
In [5]: run(['test', '-f', 'testdirectory']).returncode == 0
Out[5]: False
Checking a directory with subprocess:
In [6]: run(['test', '-d', 'testfile.txt']).returncode == 0
Out[6]: False
In [7]: run(['test', '-d', 'testdirectory']).returncode == 0
Out[7]: True
It’s not that recommended to use this option since it consumes more resources, and we’re not getting any advantage from it.
To Sum Up
Python is one of the most used programming languages to automate processes by interacting with the OS. One cool thing you can do with it is to check if a file or a folder exists.
The most straightforward to do so are:
- Opening and handling file exceptions right away
- Using the exists() function of the os.path or pathlib modules.
In this tutorial you learned:
- How to open a file and handle exceptions in case it doesn’t exist
- The meaning of paths
- 3 different functions the os.path submodule provides to check the existence of a file or folder
- Unix uses forward-slashes (/), while Windows uses back-slashes (\)
Next read: What is a Subprocess in Python? [5 Usage Examples]