If you need to drop a temp file, clean a cache directory, or undo a bad write, you want a short, safe pattern you can paste without shredding the wrong tree. Below I put pathlib.Path.unlink() first—that is what I reach for in new code—then os.remove(), “delete if exists” with missing_ok and with try/except, clearing folders, extension filters, and how folders differ from files. These APIs remove data from the disk; they do not send anything to the Trash or Recycle Bin.
Each example uses tempfile.TemporaryDirectory(): the script creates its own tiny file (or folder) inside a throwaway directory, then deletes it. You do not need a data.txt or logs/ already sitting on your machine for the sample to make sense—nothing in your real project directory is touched when you run the snippet as written. For writing files in your own apps first, see write to file; for creating directories, use the nested directories guide. Prefer check if a file exists only when you need a probe—not as a race-safe substitute for missing_ok or except FileNotFoundError.
Tested on: Python 3.13.3; kernel 6.14.0-37-generic.
Best way to delete a file in Python
The usual modern answer is two lines with pathlib:
from pathlib import Path
import tempfile
with tempfile.TemporaryDirectory() as d:
path = Path(d) / "data.txt"
path.write_text("example", encoding="utf-8")
path.unlink()
print("still there?", path.exists())You should see still there? False. Path.unlink() removes a file or symbolic link at that path. If the path is a directory, unlink is the wrong tool—use Path.rmdir() for an empty directory or shutil.rmtree() for a full tree (covered later).
Delete a file using pathlib Path.unlink()
unlink follows the rest of your Path workflow: join paths safely, then delete.
from pathlib import Path
import tempfile
with tempfile.TemporaryDirectory() as d:
target = Path(d) / "notes.txt"
target.write_text("keep me briefly", encoding="utf-8")
target.unlink()
print("gone:", not target.exists())You should see gone: True. If the target is missing and you did not pass missing_ok, Python raises FileNotFoundError—same idea as os.remove on a bad path, which ties into FileNotFoundError when you want the full error story.
Delete a file if it exists using pathlib
When you want “remove this file if it is there, otherwise do nothing,” use missing_ok=True on unlink:
from pathlib import Path
import tempfile
with tempfile.TemporaryDirectory() as d:
path = Path(d) / "optional.txt"
path.unlink(missing_ok=True)
path.write_text("x", encoding="utf-8")
path.unlink(missing_ok=True)
path.unlink(missing_ok=True)
print("done")That should print done with no exception—the second and third deletes both see an already removed file. The missing_ok parameter was added in Python 3.8; on 3.7 or older you must catch FileNotFoundError yourself or check version before relying on it.
Delete a file using os.remove()
os.remove(path) (also spelled os.unlink—see the next section) deletes a file by string path. It raises FileNotFoundError if the path does not exist.
import os
import tempfile
with tempfile.TemporaryDirectory() as d:
path = os.path.join(d, "legacy.txt")
with open(path, "w", encoding="utf-8") as f:
f.write("data")
os.remove(path)
print(os.path.exists(path))You should see False. The os.remove documentation notes platform behavior: on Windows, removing a file that another process holds open can fail; on Unix the name may disappear even if another handle keeps the inode alive until the last close.
Delete a file if it exists using try except
If you must stay on an older Python without missing_ok, or you already use os.remove, prefer handling the error instead of os.path.exists() first—a file can vanish between the check and the delete.
import os
import tempfile
with tempfile.TemporaryDirectory() as d:
path = os.path.join(d, "maybe.csv")
try:
os.remove(path)
except FileNotFoundError:
print("already absent")
with open(path, "w", encoding="utf-8") as f:
f.write("row")
os.remove(path)
print("removed once")You should see already absent then removed once. Catch FileNotFoundError specifically; a bare except: would hide real bugs. If you truly need an existence probe for other reasons, see check if a file exists, but keep deletes race-safe as above.
os.remove() vs os.unlink()
In CPython, os.remove and os.unlink are the same function with two names—unlink is the traditional Unix word, remove reads a little clearer in beginner material. Style guides such as Ruff’s pathlib rules often suggest Path.unlink() over os.unlink() when you already work with paths as Path objects for readability. There is no separate “Unix-only” unlink in Python’s os module the way some old tutorials claimed.
Delete all files in a folder
Walk files with Path.iterdir(), delete files, and skip subdirectories unless you intend to recurse (recursion deserves its own careful design).
from pathlib import Path
import tempfile
with tempfile.TemporaryDirectory() as d:
folder = Path(d)
(folder / "a.log").write_text("1", encoding="utf-8")
(folder / "b.log").write_text("2", encoding="utf-8")
(folder / "keep").mkdir()
for path in folder.iterdir():
if path.is_file():
path.unlink()
remaining = sorted(p.name for p in folder.iterdir())
print(remaining)You should see ['keep']—only the empty subdirectory remains. Adjust the loop if you also want to remove nested trees (then you are closer to rmtree territory).
Delete only files with a specific extension
Path.glob() keeps the pattern local to one directory; combine with is_file() if you want to ignore odd symlink edge cases.
from pathlib import Path
import tempfile
with tempfile.TemporaryDirectory() as d:
folder = Path(d)
(folder / "one.log").write_text("a", encoding="utf-8")
(folder / "two.log").write_text("b", encoding="utf-8")
(folder / "readme.txt").write_text("c", encoding="utf-8")
for path in folder.glob("*.log"):
path.unlink()
print(sorted(p.name for p in folder.iterdir()))You should see ['readme.txt']. For more iteration patterns, the for loop tutorial covers the basics.
Delete empty folder vs non-empty folder
Deleting a file is not deleting a folder. Use the right tool so you do not call os.remove on a directory (that raises IsADirectoryError on Unix).
| Need | Method |
|---|---|
| Delete one file or symlink | Path.unlink() or os.remove() |
| Delete an empty directory | Path.rmdir() or os.rmdir() |
| Delete a directory and everything inside | shutil.rmtree() (dangerous on wrong paths—double-check the Path you pass) |
from pathlib import Path
import shutil
import tempfile
with tempfile.TemporaryDirectory() as d:
root = Path(d)
empty = root / "empty_dir"
empty.mkdir()
empty.rmdir()
nested = root / "tree"
(nested / "sub").mkdir(parents=True)
(nested / "sub" / "f.txt").write_text("x", encoding="utf-8")
shutil.rmtree(nested)
print("tree gone:", not nested.exists())You should see tree gone: True. Path.rmdir requires an empty directory; shutil.rmtree removes a full tree—treat it like rm -rf.
Common mistakes when deleting files in Python
- Calling
os.remove()orPath.unlink()on a directory path—usermdir/rmtreeinstead. - Assuming delete means “move to Trash”—these APIs erase the filesystem entry; recovery needs backups or OS-specific APIs.
- Using
os.path.exists()immediately before delete without handling races—prefermissing_ok=Trueorexcept FileNotFoundError. - Using
Path.unlink(missing_ok=True)on Python older than 3.8 without a fallback. - Confusing
os.removewithos.rmdir—the first targets files; the second targets empty directories only. - Building paths with string concatenation instead of
Pathoros.path.join—easy to form a wrong path and delete the wrong object. - Running “delete every file in folder” loops without filtering—accidentally follow symlinks or climb into subfolders you did not mean to wipe.
Python delete file quick reference table
| Goal | Typical code |
|---|---|
| Delete one file (modern) | Path("file").unlink() |
| Delete if maybe missing (3.8+) | Path("file").unlink(missing_ok=True) |
| Delete by string path | os.remove("file") |
Delete if maybe missing (os) |
try: os.remove(...)\nexcept FileNotFoundError: pass |
| Clear files in one folder | for p in Path(dir).iterdir():\n if p.is_file(): p.unlink() |
Only .log files |
for p in Path(dir).glob("*.log"): p.unlink() |
| Remove empty directory | Path(dir).rmdir() |
| Remove directory + contents | shutil.rmtree(path) |
Summary
You now have a default pattern—Path.unlink() on a Path you built safely—plus missing_ok=True when you want idempotent deletes on Python 3.8+. os.remove stays fine for legacy string paths; pair it with try/except FileNotFoundError when you cannot use missing_ok. Clearing a folder means iterating files (often with iterdir or glob), while removing directories means rmdir for empty trees and shutil.rmtree when you truly intend to remove everything underneath. Stay explicit about permanence: none of this moves files to the Recycle Bin.

