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?
414 Answers
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 23I 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.
14As of Python 3.8, use missing_ok=True and pathlib.Path.unlink (docs here)
from pathlib import Path my_file = Path("./dir1/dir2/file.txt") # Python 3.8+ my_file.unlink(missing_ok=True) # Python 3.7 and earlier if my_file.exists(): my_file.unlink() 2os.path.exists returns True for folders as well as files. Consider using os.path.isfile to check for whether the file exists instead.
In the spirit of Andy Jones' answer, how about an authentic ternary operation:
os.remove(fn) if os.path.exists(fn) else None 8if 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".
3Another 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.
0Matt'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() In Python 3.4 or later version, the pythonic way would be:
import os from contextlib import suppress with suppress(OSError): os.remove(filename) 1Something 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") 3Since 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 OSErrorFileNotFoundError pass A KISS offering:
def remove_if_exists(filename): if os.path.exists(filename): os.remove(filename) And then:
remove_if_exists("my.file") 4This is another solution:
if os.path.isfile(os.path.join(path, filename)): os.remove(os.path.join(path, filename)) This will do in one line as well as checks if the path exists, else nothing really happens
os.remove(my_path) if os.path.exists(my_path) else None