• Get application security done the right way! Detect, Protect, Monitor, Accelerate, and more…
  • 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.

    Ipython interactive shell running Python 3.9

    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]