This article continues with our series on interacting with the file system in Python. The previous articles dealt with reading and writing files. Interestingly, the file system is much more than a way to store/retrieve data to disk. There are also various other types of entries such as files, directories, sockets (for inter-process communication), named pipes, both soft and hard links, as well as special files (block devices). Reading and writing from and to them is done in a similar way as we saw in the previous articles.
This article focuses on the handling of directories. Other operating systems, like UNIX/Linux, instead use a different terminology, where an "entry" is named a "folder". Next, we will show you how to identify the current working directory, how to create both a persistent and a temporary, single directory as well as nested directory structures with subfolders, and how to remove a directory if no longer needed. Therefore, the two Python modules os
and tempfile
come into play.
Required Python Modules
Reading and writing files does not require loading an additional module, but accessing the file system functions (like handling directories) requires that we use a separate module. First, the os
module has to be loaded. os
is a Python module which belongs to the core part of the Python ecosystem. It is done using an import statement as follows:
import os
The os
module contains most of the methods we'll need throughout this article. However, as you'll see later on, if you want to something more advanced, like create a temporary file for storing data, then we'll also be needing the tempfile
module.
Detecting the Current Working Directory
Before we get in to creating/removing directories, let's see how to perform some other basic directory operations, like detecting the current working directory using the method getcwd()
. This method will return a string containing the path of your working directory. Listing 1 shows how to integrate this method in a Python script.
# import the os module
import os
# detect the current working directory and print it
path = os.getcwd()
print ("The current working directory is %s" % path)
Listing 1
The output should look something like this:
$ python3 cwd.py
The current working directory is /home/frank/
Furthermore, the os
module contains the additional getcwdb()
method. This one is similar to the getcwd()
method but returns the path as a binary string, instead.
There are quite a few other directory operations not covered in this article, like checking if a file or directory exists. But for now we'll move on to the main purpose of this article.
Creating a Directory
Creating a single directory is done using the mkdir()
method. As a parameter, mkdir()
first requires the path name for the directory in order for it to be created. For an example, see the code below:
import os
# define the name of the directory to be created
path = "/tmp/year"
try:
os.mkdir(path)
except OSError:
print ("Creation of the directory %s failed" % path)
else:
print ("Successfully created the directory %s " % path)
Listing 2
Keep in mind that the mkdir()
method cannot create sub-directories on a deeper level than one in a single call. To create an entire path you have to call mkdir()
once per directory level. Alternatively, if you want to create multiple directories at once, make use of the makedirs()
method instead (which you can see in Listing 4 below).
As an optional parameter you can specify the access rights to the directory within your mkdir()
call. The default setting is 777, which means it is readable and writable by the owner, group members, and all other users as well. In case you require a more restrictive setting, like 755, (readable and accessible by all users, and write access by only the owner) you may call it as follows:
import os
# define the name of the directory to be created
path = "/tmp/year"
# define the access rights
access_rights = 0o755
try:
os.mkdir(path, access_rights)
except OSError:
print ("Creation of the directory %s failed" % path)
else:
print ("Successfully created the directory %s" % path)
Listing 3
One thing to note about this code - you may have noticed that the access rights (755 here) are specified using the octal prefix (0o
), which is done so you don't need to convert the number to decimal first. Since the OS represents the access permissions as octal, that's how we'll represent them here too.
However, as the Python documentation states, some systems ignore the mode
parameter and you should use os.chmod
instead.
Creating a Directory with Subdirectories
As already mentioned above, the mkdir()
method allows us to create a single directory, only. To create multi-level subdirectories the makedirs()
method comes into play. Actually, makedirs()
is implemented in such a way that it calls mkdir()
to create one directory after the next.
As a parameter makedirs()
accepts the entire path to be created. This method is similar to the UNIX/Linux command mkdir -p
. Listing 4 shows an example of how to use this method.
import os
# define the name of the directory to be created
path = "/tmp/year/month/week/day"
try:
os.makedirs(path)
except OSError:
print ("Creation of the directory %s failed" % path)
else:
print ("Successfully created the directory %s" % path)
Listing 3
Creating a Temporary Directory
So far, we've created permanent entries in the file system. For various reasons like parking data temporarily it can be necessary to just have a temporary directory. The tempfile
module contains methods that handle such cases in a safe and consistent way.
Listing 5 shows an example that uses the TemporaryDirectory()
method in combination with the with
statement. After the with
statement the temporary directory does not exist anymore because both the directory, and its contents have been entirely removed.
import tempfile
# create a temporary directory
with tempfile.TemporaryDirectory() as directory:
print('The created temporary directory is %s' % directory)
# directory and its contents have been removed by this point
Listing 5
Listing 6 shows the output of the Python script from Listing 5. In order to create temporary files, on UNIX/Linux systems the three directories /tmp, /var/tmp, and /usr/tmp are tried, and the first match of them is taken. In this current case it is the /tmp directory that is used.
Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!
$ python3 mkdir-temporary.py
The created temporary directory is /tmp/tmpf6o0hy3c
Listing 6
Deleting a Directory
Deleting a directory is the opposite case of creating one. You can do that using the rmdir()
method of the os
module. rmdir()
requires a path string that contains the directory name, and only deletes the deepest entry in the path string. Note that this only works when the directory is entirely empty. If it is not empty then an OSError
is raised. Listing 7 shows the according Python code.
import os
# define the name of the directory to be deleted
path = "/tmp/year"
try:
os.rmdir(path)
except OSError:
print ("Deletion of the directory %s failed" % path)
else:
print ("Successfully deleted the directory %s" % path)
Listing 7
In case you would like to remove an entire directory tree the rmtree()
method from the shutil
module will help you with that task.
Conclusion
As you may have noted, handling directories is very simple in Python. It takes you only a few lines of code to create and to remove this kind of file entry.
Links and References
- The Linux Documentation project (TLDP), General overview of the Linux
file system, Files
Acknowledgements
The author would like to thank Zoleka Hatitongwe for her support while preparing the article.