How to delete a file in Python

Learn how to delete a file in Python using different methods. Discover tips, real-world applications, and how to debug common errors.

How to delete a file in Python
Published on: 
Fri
Feb 6, 2026
Updated on: 
Mon
Apr 13, 2026
The Replit Team

File deletion in Python is a common task for script automation and file system management. Python's built-in modules, like os, offer simple and effective functions for this purpose.

In this article, you'll learn several techniques to remove files. You will find practical tips, real-world applications, and common debugging advice to help you manage files safely and efficiently.

Using os.remove() to delete a file

import os

file_path = "example.txt"
with open(file_path, "w") as f:
f.write("Test content")

os.remove(file_path)
print(f"File '{file_path}' has been deleted")--OUTPUT--File 'example.txt' has been deleted

The os.remove() function is the most direct way to delete a single file through system-level file operations. It takes the file path as its only argument and removes that file from your filesystem. The example first creates example.txt simply to ensure the deletion command has a file to act on.

It's important to know that if the path doesn't point to an existing file, Python will raise a FileNotFoundError. This is why robust scripts often check if a file exists before attempting to remove it, preventing unexpected crashes.

Basic file deletion techniques

Building on os.remove(), you can also use alternatives like os.unlink() or the modern pathlib module for handling file and directory deletions.

Using os.unlink() as an alternative

import os

file_path = "example.txt"
with open(file_path, "w") as f:
f.write("Test content")

os.unlink(file_path)
print(f"File '{file_path}' has been deleted")--OUTPUT--File 'example.txt' has been deleted

The os.unlink() function is functionally identical to os.remove(). Its name comes from its UNIX heritage, where deleting a file is described as removing a hard link to the file's data on the disk. For all practical purposes in Python, you can consider them interchangeable.

  • Like its counterpart, os.unlink() will raise a FileNotFoundError if the specified file doesn't exist.
  • The choice between them often comes down to personal preference or team coding standards.

Deleting files with pathlib.Path

from pathlib import Path

file_path = Path("example.txt")
file_path.write_text("Test content")

file_path.unlink()
print(f"File '{file_path}' has been deleted")--OUTPUT--File 'example.txt' has been deleted

The pathlib module provides a modern, object-oriented way to interact with filesystem paths. Instead of passing a string to a function, you create a Path object that represents the file. This object has its own methods for file operations, making your code more intuitive.

  • The unlink() method deletes the file the Path object points to, performing the same action as os.remove().
  • This approach is often preferred because it bundles the path and the operations you can perform on it together.
  • Like the other functions, it raises a FileNotFoundError if the file doesn't exist.

Removing directories with shutil.rmtree()

import os
import shutil

os.makedirs("test_dir", exist_ok=True)
with open("test_dir/file.txt", "w") as f:
f.write("Test content")

shutil.rmtree("test_dir")
print("Directory 'test_dir' and all its contents have been deleted")--OUTPUT--Directory 'test_dir' and all its contents have been deleted

When you need to delete an entire directory and not just a single file, the shutil module is your go-to tool. The shutil.rmtree() function recursively removes a directory, including all files and subdirectories within it. It's a powerful command, so you should use it with care. This complements creating directories in Python.

  • Unlike os.remove(), which fails on directories, shutil.rmtree() is designed to handle entire directory trees.
  • Be aware that this operation is irreversible. Once the directory is gone, its contents are gone for good.

Advanced file deletion techniques

Knowing the basic deletion commands is one thing, but writing robust scripts that handle errors and work on multiple files requires a few more tricks.

Safely handling exceptions during deletion

import os

file_path = "nonexistent_file.txt"
try:
os.remove(file_path)
print(f"File '{file_path}' has been deleted")
except FileNotFoundError:
print(f"Error: The file '{file_path}' does not exist")
except PermissionError:
print(f"Error: No permission to delete '{file_path}'")--OUTPUT--Error: The file 'nonexistent_file.txt' does not exist

Wrapping your os.remove() call in a try...except block is crucial for writing robust code, as it prevents your script from crashing if the deletion fails. Instead of halting, your program can catch the error and handle it gracefully, like printing a helpful message.

This example specifically prepares for two common problems, demonstrating basic techniques for handling multiple exceptions:

  • FileNotFoundError: This is caught when the target file doesn't exist, which is a frequent occurrence in file management tasks.
  • PermissionError: This handles situations where your script lacks the necessary operating system rights to delete the file.

Checking file existence before deletion

import os

file_path = "example.txt"
if os.path.exists(file_path):
os.remove(file_path)
print(f"File '{file_path}' has been deleted")
else:
print(f"The file '{file_path}' does not exist")--OUTPUT--The file 'example.txt' does not exist

Instead of handling exceptions after they occur, you can proactively check if a file exists before attempting deletion. The os.path.exists() function returns True if the file is found, letting your script safely proceed with os.remove(). This is a direct way to avoid a FileNotFoundError.

  • This method is often clearer than a try...except block if the only error you expect is a missing file.
  • It's a classic example of the "Look Before You Leap" (LBYL) coding style.

Deleting multiple files with pattern matching

import os
import glob

# Create some test files
for i in range(3):
with open(f"test_{i}.txt", "w") as f:
f.write(f"Content {i}")

# Delete all matching files
for file_path in glob.glob("test_*.txt"):
os.remove(file_path)
print(f"Deleted: {file_path}")--OUTPUT--Deleted: test_0.txt
Deleted: test_1.txt
Deleted: test_2.txt

When you need to delete many files at once, the glob module is incredibly useful. It lets you find files using patterns, much like you would in a command-line shell. The glob.glob() function takes a pattern and returns a list of all file paths that match it.

  • In this example, the pattern test_*.txt uses an asterisk (*) as a wildcard to match any characters. It finds all files starting with test_ and ending with .txt.
  • The code then loops through the list of found files and deletes each one using os.remove().

Move faster with Replit

Replit is an AI-powered development platform that comes with all Python dependencies pre-installed, so you can skip setup and start coding instantly. From here, you can move beyond learning individual techniques and build complete applications with Agent 4.

Instead of piecing together code, you can describe the app you want to build and the Agent will handle the rest—from writing code to deployment. For example, you could create practical tools that use file deletion, such as:

  • A temporary file cleaner that periodically scans a directory and removes files with specific extensions, like .tmp or .log.
  • A digital asset manager that deletes old versions of files after a new version is uploaded, keeping your storage tidy.
  • A development utility that cleans a project by removing all compiled Python files (*.pyc) and empty subfolders before deployment.

Simply describe your app, and Replit will write the code, test it, and fix issues automatically, all within your browser.

Common errors and challenges

When deleting files in Python, you might encounter a few common issues, but they're all manageable with the right approach.

  • Handling files that are still open: Trying to delete a file that's currently open is a classic snag. If your script or another process has a lock on the file, calling os.remove() will typically raise a PermissionError. The best practice is to ensure files are closed before you try to delete them—using a with open(...) block is a great way to manage this, as it automatically closes the file for you.
  • Deleting read-only files: Another hurdle is dealing with read-only files. Your operating system protects these files, so a standard os.remove() call will fail with a PermissionError. To get around this, you need to first change the file's permissions to make it writable, which you can do with Python's os.chmod() function.
  • Avoiding race conditions: A race condition occurs when you check if a file exists with os.path.exists(), but another process deletes it before your script can call os.remove(). A more robust solution is to skip the check and just try deleting the file directly within a try...except FileNotFoundError block, which gracefully handles cases where the file is already gone.

Handling files that are still open when using os.remove()

One of the most common errors you'll face is trying to delete a file that your script still has open. Operating systems often lock the file, preventing its removal. The following code demonstrates what happens when you call os.remove() without closing the file first.

import os

# Create and open a file
file_path = "data.txt"
file = open(file_path, "w")
file.write("Some data")

# Try to delete while still open
os.remove(file_path) # This will raise an error on Windows
print(f"File '{file_path}' has been deleted")

Because the file handle isn't closed before calling os.remove(), the operating system keeps the file locked, which triggers an error. The correct approach ensures the file is released before deletion, as shown in the next example.

import os

# Create and open a file
file_path = "data.txt"
file = open(file_path, "w")
file.write("Some data")

# Close the file before deleting
file.close()
os.remove(file_path)
print(f"File '{file_path}' has been deleted")

The solution is to explicitly close the file before you try to delete it. Calling file.close() releases the operating system's lock, allowing os.remove() to work without raising a PermissionError.

It's a crucial step to remember whenever you manually open a file with open() instead of using a with statement, which handles closing automatically. This simple action prevents your script from crashing when managing files it has just created or modified.

Deleting read-only files with proper permissions

Read-only files are protected by the operating system, so a simple os.remove() call won't work. This protection prevents accidental deletion. The following code demonstrates what happens when you try to delete a file without first changing its permissions.

import os
import stat

# Create a file and make it read-only
file_path = "readonly.txt"
with open(file_path, "w") as f:
f.write("Protected content")

os.chmod(file_path, stat.S_IREAD) # Make file read-only

# Try to delete the read-only file
os.remove(file_path) # Will fail on some systems
print(f"File '{file_path}' has been deleted")

The os.chmod() call makes the file read-only, so os.remove() fails with a PermissionError. The operating system is simply protecting the file as instructed. The next example shows how to work around this.

import os
import stat

# Create a file and make it read-only
file_path = "readonly.txt"
with open(file_path, "w") as f:
f.write("Protected content")

os.chmod(file_path, stat.S_IREAD) # Make file read-only

# Change permissions before deleting
os.chmod(file_path, stat.S_IWRITE | stat.S_IREAD)
os.remove(file_path)
print(f"File '{file_path}' has been deleted")

To delete a read-only file, you first need to change its permissions. The code uses os.chmod() with the stat.S_IWRITE flag to make the file writable again. By combining it with stat.S_IREAD using the | operator, you ensure both read and write permissions are set.

After updating the permissions, the os.remove() call works as expected. This is a common step when your script needs to manage files that might be protected.

Avoiding race conditions with os.path.exists() checks

A race condition occurs when the time between checking for a file with os.path.exists() and deleting it with os.remove() is just long enough for another process to interfere. This can cause your script to crash unexpectedly.

The following example demonstrates this potential pitfall, where checking first isn't always the safest bet.

import os

file_path = "shared_file.txt"

# This approach can lead to race conditions
if os.path.exists(file_path):
# Another process might delete the file here before we do
os.remove(file_path)
print(f"File '{file_path}' has been deleted")
else:
print(f"The file '{file_path}' does not exist")

The problem with this 'look before you leap' approach is the time gap. If another process deletes the file after your os.path.exists() check but before your os.remove() call, your script will crash. The next example shows a more robust way to handle this.

import os

file_path = "shared_file.txt"

# Use try-except to handle the file deletion atomically
try:
os.remove(file_path)
print(f"File '{file_path}' has been deleted")
except FileNotFoundError:
print(f"The file '{file_path}' does not exist")

This "Easier to Ask for Forgiveness than Permission" approach is more robust. By wrapping os.remove() in a try...except block, you attempt the deletion directly instead of checking first. If the file is already gone, your script simply catches the FileNotFoundError and continues without crashing. This method is ideal for avoiding race conditions, especially in applications where multiple processes might be managing the same files simultaneously, as it makes the operation safer.

Real-world applications

Moving beyond error handling, you can combine these techniques with vibe coding to build practical tools for cleaning old files or creating a recycling bin.

Deleting files based on modification time with os.path.getmtime()

To keep directories tidy, you can use os.path.getmtime() to fetch a file's last modification timestamp and remove any files older than a specified age. This is particularly useful for managing log directories where creating log files regularly can lead to storage issues.

import os
import time

# Create a test directory with an old file
os.makedirs("logs", exist_ok=True)
with open("logs/old_log.txt", "w") as f:
f.write("Old log content")
os.utime("logs/old_log.txt", (time.time() - 30*86400, time.time() - 30*86400))

# Delete files older than 14 days
for file in os.listdir("logs"):
path = os.path.join("logs", file)
if time.time() - os.path.getmtime(path) > 14*86400:
os.remove(path)
print(f"Deleted old file: {path}")

This script provides a blueprint for automatically purging old files. It first creates a test file and uses os.utime to artificially age it by 30 days. The main loop then scans the logs directory with os.listdir. Inside the loop, it calculates the time since each file was last modified by subtracting its os.path.getmtime() timestamp from the current time.time(). If the file is older than 14 days, os.remove() deletes it. For scripts that need to work across different directories, changing working directory becomes essential.

Implementing a recycling bin with shutil.move()

Instead of deleting files permanently, you can use shutil.move() to create a simple recycling bin that moves them to a different directory, giving you a chance to recover them later.

import os
import shutil

# Setup recycle bin and test file
os.makedirs("recycle_bin", exist_ok=True)
with open("important_doc.txt", "w") as f:
f.write("Important content")

# Move to recycle bin instead of deleting
if os.path.exists("important_doc.txt"):
shutil.move("important_doc.txt", "recycle_bin/important_doc.txt")
print("File moved to recycle bin instead of being deleted")
print(f"Files in recycle bin: {os.listdir('recycle_bin')}")

This script demonstrates how to organize files by moving them to a different location. The core of the operation is shutil.move(), which transfers important_doc.txt into a newly created recycle_bin directory. This is a common pattern for archiving files instead of deleting them outright.

  • The script uses os.makedirs() with exist_ok=True to safely create the destination folder without causing an error if it already exists.
  • An if os.path.exists() check confirms the file is present before the move, which helps prevent potential errors and makes the script more robust.

Get started with Replit

Now, turn these techniques into a real tool with Replit Agent. Describe what you want, like "a script to find and delete duplicate files in a directory" or "a utility that clears out temporary cache folders."

Replit Agent will write the code, test for errors, and deploy your application for you. Start building with Replit.

Build your first app today

Describe what you want to build, and Replit Agent writes the code, handles the infrastructure, and ships it live. Go from idea to real product, all in your browser.

Build your first app today

Describe what you want to build, and Replit Agent writes the code, handles the infrastructure, and ships it live. Go from idea to real product, all in your browser.