Scott C Wilson
Scott C Wilson

Reputation: 20036

Most pythonic way to delete a file which may not exist

I want to delete the file filename if it exists. Is it proper to say

if os.path.exists(filename):
    os.remove(filename)

Is there a better way? A one-line way?

Upvotes: 680

Views: 468623

Answers (14)

BATMAN
BATMAN

Reputation: 373

If glob is available.

for file in glob.glob("file/matching/pattern/*.csv"):
    os.remove(file)

Upvotes: -1

wkeithvan
wkeithvan

Reputation: 2145

As of Python 3.8, use pathlib.Path.unlink with the missing_ok=True kwarg (docs here).

Otherwise, a try/except block is the best way to do it as it is thread-safe (unlike an if/else block that checks if the file exists). In Python 3.3, the FileNotFoundError was introduced as a subclass of OSError specific to the file not existing and in Python 3.4 pathlib was added as a cleaner way to deal with the file system. So...

import pathlib  # Python >= 3.4
import os       # Python < 3.4

# Python 3.8+
pathlib.Path("./dir/file.txt").unlink(missing_ok=True)

# Python 3.4-3.7
try:
    pathlib.Path("./dir/file.txt").unlink()
except FileNotFoundError:
    pass

# Python 3.3
try:
    os.remove("./dir/file.txt")
except FileNotFoundError:
    pass

# Python 3.2 and earlier
try:
    os.remove("./dir/file.txt")
except OSError:
    pass
    

Upvotes: 151

Paul
Paul

Reputation: 6911

Since Python 3.3 you can use FileNotFoundError which is more correct than the accepted version since it doesn't ignore other possible errors.

try:
    os.remove(filename)
except FileNotFoundError:
    pass

Upvotes: 5

Tim Keating
Tim Keating

Reputation: 6641

In the spirit of Andy Jones' answer, how about an authentic ternary operation:

os.remove(fn) if os.path.exists(fn) else None

Upvotes: 51

Kian
Kian

Reputation: 1350

This is another solution:

if os.path.isfile(os.path.join(path, filename)):
    os.remove(os.path.join(path, filename))

Upvotes: -1

Jason R. Coombs
Jason R. Coombs

Reputation: 42694

Matt's answer is the right one for older Pythons and Kevin's the right answer for newer ones.

If you wish not to copy the function for silentremove, this functionality is exposed in path.py as remove_p:

from path import Path
Path(filename).remove_p()

Upvotes: 9

Baz
Baz

Reputation: 13145

A KISS offering:

def remove_if_exists(filename):
  if os.path.exists(filename):
    os.remove(filename)

And then:

remove_if_exists("my.file")

Upvotes: 0

Ross Castroverde
Ross Castroverde

Reputation: 71

In Python 3.4 or later version, the pythonic way would be:

import os
from contextlib import suppress

with suppress(OSError):
    os.remove(filename)

Upvotes: 3

DevonMcC
DevonMcC

Reputation: 465

if os.path.exists(filename): os.remove(filename)

is a one-liner.

Many of you may disagree - possibly for reasons like considering the proposed use of ternaries "ugly" - but this begs the question of whether we should listen to people used to ugly standards when they call something non-standard "ugly".

Upvotes: 22

Matt
Matt

Reputation: 22153

A more pythonic way would be:

try:
    os.remove(filename)
except OSError:
    pass

Although this takes even more lines and looks very ugly, it avoids the unnecessary call to os.path.exists() and follows the python convention of overusing exceptions.

It may be worthwhile to write a function to do this for you:

import os, errno

def silentremove(filename):
    try:
        os.remove(filename)
    except OSError as e: # this would be "except OSError, e:" before Python 2.6
        if e.errno != errno.ENOENT: # errno.ENOENT = no such file or directory
            raise # re-raise exception if a different error occurred

Upvotes: 830

Kevin
Kevin

Reputation: 30171

I prefer to suppress an exception rather than checking for the file's existence, to avoid a TOCTTOU bug. Matt's answer is a good example of this, but we can simplify it slightly under Python 3, using contextlib.suppress():

import contextlib

with contextlib.suppress(FileNotFoundError):
    os.remove(filename)

If filename is a pathlib.Path object instead of a string, we can call its .unlink() method instead of using os.remove(). In my experience, Path objects are more useful than strings for filesystem manipulation.

Since everything in this answer is exclusive to Python 3, it provides yet another reason to upgrade.

Upvotes: 280

jotacor
jotacor

Reputation: 3087

Another way to know if the file (or files) exists, and to remove it, is using the module glob.

from glob import glob
import os

for filename in glob("*.csv"):
    os.remove(filename)

Glob finds all the files that could select the pattern with a *nix wildcard, and loops the list.

Upvotes: 8

abought
abought

Reputation: 2680

os.path.exists returns True for folders as well as files. Consider using os.path.isfile to check for whether the file exists instead.

Upvotes: 58

Andy Jones
Andy Jones

Reputation: 6275

Something like this? Takes advantage of short-circuit evaluation. If the file does not exist, the whole conditional cannot be true, so python will not bother evaluation the second part.

os.path.exists("gogogo.php") and os.remove("gogogo.php")

Upvotes: 0

Related Questions