Deleting Files and Directories
00:00 Now that you know how to create and list files and directories, along with their attributes, it would be great if you could delete them whenever you were done with them.
00:09 And that, of course, will be the topic of this lesson: deleting files and directories.
00:15 I’m going to split the rest of this lesson into two parts. The first will be deleting files and the second will be on deleting directories. To delete files you have a few options, as usual.
00:26
With the os
module you actually have two almost identical functions: os.remove()
and os.unlink()
, both of which take in a string file_path
and delete that single file, not a directory.
00:38
They raise FileNotFound
if the file doesn’t exist. And the reason that there are two identical functions with different names is just a question of compatibility with different programming paradigms, some people in old or, kind of, Unix systems like to use unlink()
as their preferred nomenclature, whereas some other people in different systems use remove()
.
00:57
It’s just to make sure everyone’s happy. With the pathlib
module, you also have an .unlink()
method, but this is a method of a Path
object.
01:05
So, as usual, you have to instantiate that Path
object before you can call .unlink()
.
01:11 The sample directory that I’ll use for both the deleting files and the deleting directory sections of this lesson will be the same. I have a couple of subfolders with files within them, and then I just have a couple of files in the top-level sample directory.
01:25
Okay, let’s take a look at how all this works in practice. I’ll use os.listdir()
to show you where I am in my filesystem. As you can see, it’s the same as I demonstrated on the slide.
01:37 I have a couple of text files in here, and then I have a couple of folders here I could show you, as well, just to make totally sure that these folders have what we expect to be in them: a few Python files, and the other folder has some stuff in it too.
01:50
So, that’s exciting! It gives us a lot of stuff to delete. First, let’s try out the os.remove()
option here, and I’ll just call it on one of these top-level text files, just for fun.
02:00
os.remove()
, it doesn’t give you any particular output but trust that it has worked, and you can check that by, again, using listdir()
and you can see 'test1.txt'
is gone.
02:12
So that’s pretty good. It works just as expected. And then os.unlink()
works in exactly the same way. I’ll call this on 'test2.txt'
.
02:21
And, as you can see, os.listdir()
, both of those text files are gone. All I have left is a few folders. And now, just to demonstrate, I want to show you here, as you can see, os.remove()
takes in a path
parameter, then a dir_fd
parameter, which I won’t get super into but you can check that out in the documentation then unlink()
.
02:42 I just want to show you that these take exactly the same arguments, just so that you can know that these really do have, essentially, the exact same behavior.
02:49
Now, I don’t really have much left to work with here, so I’ll use one of these files in folder_1/
. So let’s say, folder_1/file1.py
to demonstrate the pathlib.Path()
behavior.
03:02
So I’ll say, file_path = Path
of "folder_"
—what did I say, "1"
? Yep, "/file1.py")
. Perfect. So now I have a Path
object, and now I can say file_path.unlink()
.
03:17
And if I now do os.listdir()
, and I call this on "folder_1"
, as you can see, that file has been deleted. So, this all seems to work perfectly.
03:28 I just want to show you real quick at the end of this section, that if you call this on something that does not exist,
03:37
then it will raise a FileNotFound
error. That will be the same behavior with all of these different functions. All of these have the same behavior when no such file is found.
03:46
I also want to show you that if I try to call—let’s do ".unlink()"
, just for variety—if I try to call this on "folder_2"
, let’s say, "folder_2"
, just to get that some touch there, then I’ll get an Operation not permitted
, because the unlink()
function is not built to work on directories, so this operation will not be allowed.
04:07 So, that’s how these functions work. Now, let’s head back and look at how directories work—deleting directories. For deleting directories, you have a similar kind of panoply of options here.
04:18
You can use os.rmdir()
, remove directory, where you pass in the directory path, and then you delete the single directory—or that’s what the function does, is it deletes the single directory.
04:30
If the directory is non-empty, though, it raises an OSError
, because it doesn’t want you to accidentally delete full directories. It wants to make sure that they’re cleared out before you delete them.
04:39
pathlib.Path.rmdir()
is identical, except it operates on a Path
object, as usual. So, create the path first, then call its .rmdir()
method.
04:49
If you need to delete non-empty directories, or an entire directory tree, you can use shutil
. You have to import shutil
, which is short for shell util, and then it has an rmtree()
function, where you can call that on a directory path and it will delete the entire directory tree rooted at this path.
05:09 So, if you have some subfolders inside this directory that you’re calling it on, those will all be deleted, too, no matter if they’re full or empty. So, this is kind of the nuclear option, of deleting directories in Python.
05:21 Again, here’s the sample directory that I’m using. Let’s go check it out in the REPL. All right, let’s delete some directories. So first, I’ll show you the filesystem here, as you can see, I’ve replenished it from earlier in this lesson when I deleted a bunch of stuff.
05:36
Now it’s back to normal. So, let’s make a first try here and just see what happens if you call os.rmdir()
on 'folder_1'
. And, of course, I have to put that in strings because it needs to be the path rather than—there’s no variable called folder_1
.
05:52
So, as you can see, this raises an OSError
because the directory is not empty. Because, of course, if I call os.listdir()
on 'folder_1'
, it has Python files in it.
06:02
So, that’s not going to work. If I want to actually delete something using os.rmdir()
—I’m going to have to really quickly just make a new directory, which I’ll just call 'test'
—and then I’ll have to listdir()
to show you that it’s in there.
06:14
So, now there’s a test/
directory, and this test/
directory is, in fact, empty, so it can be deleted. This might seem like an inconvenient feature, that you can only delete, with these basic things, directories that are empty.
06:27 But really, it’s just a safety feature. It doesn’t want you to delete stuff when there might be useful files within that directory. It doesn’t want you to delete that without, at least, thinking about what’s in it.
06:38
Now, though, I can say os.rmdir('test')
, and now you can see it’s back, it’s gone again. But I’m going to create it one more time to show you that I can now do the same thing with the pathlib
module.
06:50
I can say dir_path = Path('test')
, and then I can say dir_path.rmdir()
, and now I’ll take a look again. I created it here, and then I created a Path
object, then I removed it, and look, it’s back to gone again.
07:07 Everything is just as it was. So this works quite well, and it’s quite easy. Now I’ll show you how you can actually delete one of these non-empty folders.
07:15
For that, you’ll have to import shell util, shutil
, and then you can simply say shutil.rmtree('folder_1')
.
07:26
And now, if I do my listdir()
here, folder_1/
is totally gone, even though it had contents in it, right? And this works even for subdirectories.
07:36
So if I say os.mkdir('folder_2/newdir')
07:42
and then I’ll just quickly show it to you, so I’ll list folder_2
. It has this 'newdir'
in it, along with these Python files. If I do, now, shutil.rmtree('folder_2')
then it’s still totally gone and that subdirectory, it was also deleted.
08:00 So this really is the heavy-hitter option, which just deletes everything without caring what’s in it. And so this can be really useful if you know that everything in your folder is garbage that you can delete.
08:09 But if you don’t know that, you should be really careful and try to use these other functions that will warn you by throwing an error, if you’re trying to delete something that has useful things in it.
08:20 So, that’s how you can delete files and directories in Python after you’ve learned to create them, and all that sort of stuff. In the next lesson, I’ll cover how to search for specific files and directories in your filesystem.
08:32 And this works in really well with deletion because, as I was saying, you want to be really careful about what you delete. So learning filename pattern matching will be a really helpful tool in making sure that you’re really careful about your file operations.
Liam Pulsifer RP Team on Sept. 8, 2020
Thanks for the note @Doc Developer! Glad to have this in the comments for posterity. Also glad you enjoyed the course :)
Become a Member to join the conversation.
Doc Developer on Aug. 28, 2020
Hey.
os.makedirs
also has theexist_ok=
parameter. Maybe it’s something worth mentioning in the “Making Directories” chapter.On a side note, great course. Thank you!