How to Recursively Delete Directories in Python
Recursively deleting a directory (removing the directory and all of its contents, including subdirectories and files) is a powerful, but potentially dangerous operation.
This guide explains how to safely and correctly delete directories recursively in Python using shutil.rmtree()
and pathlib
, covering error handling and best practices.
Using shutil.rmtree()
(Recommended)
The shutil.rmtree()
function from the shutil
module is the standard and safest way to recursively delete a directory and its contents in Python.
import shutil
import os
path_to_directory = './my-directory'
# Check if the directory exists before attempting to delete.
if os.path.isdir(path_to_directory):
shutil.rmtree(path_to_directory)
print('Directory deleted successfully')
else:
print('The specified directory does NOT exist')
# The directory should no longer exist. Verify.
print(os.path.isdir(path_to_directory)) # Output: False
shutil.rmtree(path_to_directory)
: This line performs the recursive deletion.- Important: Always ensure that
path_to_directory
actually points to a directory (and not a symbolic link to a directory) before callingrmtree()
. - The
os.path.isdir()
checks if the directory exists. - Relative vs. Absolute Paths: You can use both relative paths (like
./my-directory
) and absolute paths (like/home/user/my-directory
orC:\\Users\\user\\my-directory
).
Handling Errors with ignore_errors=True
Sometimes, files within the directory might be read-only, or you might not have sufficient permissions to delete everything. The ignore_errors=True
argument tells rmtree()
to skip over these errors and continue deleting as much as possible:
import shutil
import os
path_to_directory = './my-directory'
shutil.rmtree(path_to_directory, ignore_errors=True)
print(os.path.isdir(path_to_directory)) # Check if directory exists.
- This example uses the
ignore_errors=True
which will skip the errors.
Handling Errors with onerror
You can also handle the errors by providing the onerror
argument:
import shutil
import os
path_to_directory = './my-directory'
def handle_error(function, path, excinfo):
print('function', function)
print('path: ', path)
print('exception info: ', excinfo)
shutil.rmtree(path_to_directory, onerror=handle_error)
- The
onerror
argument accepts a function that takes three arguments: the function that raised the exception, the path and the exception.
Handling Errors with try
/except
You can use try
/except
blocks to handle exceptions during the deletion:
import shutil
import os
path_to_directory = './my-directory'
try:
shutil.rmtree(path_to_directory)
print('Recursively deleted directory')
except Exception as e:
print('Exception: ', e)
- The
shutil.rmtree
function might raise anOSError
, orFileNotFoundError
so you can handle them using atry/except
block.
Checking for Existence Before Deletion
It's a good practice to check if the directory exists before attempting to delete it, as attempting to delete a non-existent directory will raise an exception:
import shutil
import os
path_to_directory = './my-directory'
if os.path.isdir(path_to_directory):
shutil.rmtree(path_to_directory)
print('Directory deleted successfully')
else:
print('The specified directory does NOT exist')
print(os.path.isdir(path_to_directory)) # Check again to verify deletion.
Using pathlib
(Recursive Deletion)
The pathlib
module offers an object-oriented way to interact with the file system. While pathlib
has rmdir()
, it only works on empty directories. To recursively delete, you need to iterate and delete contents first. This approach is more complex than shutil.rmtree()
and provides no real benefit for this specific task, so shutil.rmtree()
is still recommended.
from pathlib import Path
def recursively_remove_dir(dir_path):
directory = Path(dir_path)
for item in directory.iterdir():
if item.is_dir():
recursively_remove_dir(item) # Recursive call for subdirectories
else:
item.unlink() # Delete files
directory.rmdir() # Delete the (now empty) directory
print(f'Recursively deleted directory {dir_path}')
path_to_directory = './my-directory'
recursively_remove_dir(path_to_directory)
- The code creates a
Path
object and iterates over the directory's subdirectories and files. - If an item is a directory, it makes a recursive call.
- If a file is found, it is removed using
unlink()
. - After iterating over all files and subdirectories the root directory is removed using
rmdir()
.