Directories and files are crucial to a programmer who wants a resource for his programs. That is why it is necessary after discussing python’s file handling methods, one should also undertake an understanding of python’s directory handling methods or routines. In this post, I will describe 5 routine ways one can handle directories using the methods provided in python such as the python make directory method and get working directory methods.
To be able to run any of the commands in this post, you first need to import the os module into your interpreter. To do that you use the code: import os
.
Getting the python current directory
The current directory is the directory from which the python interpreter is operating. It depends on how you launch your interpreter or your editor. To know your current working directory is easy. You just need to call the python get current working directory method, os.getcwd(). Here is an example:
import os
working_dir = os.getcwd()
print(working_dir)
The code above will make the current working directory to be printed on your terminal.
You might desire to change your current working directory. Maybe you want to do some experiment on some programs and want to run them on a directory you intend to delete later; I do that all the time. Changing the current working directory is easy with python. You use the python change working directory method, whose syntax is: os.chdir(path). It states that you have to provide a path as an argument for the directory you want to switch to. Path should be based on the path specification of your operating system. It is wise to make path a string in all cases.
An example will suffice.
import os
os.chdir('C:\\Users\\Michael\\Desktop\\')
print(os.getcwd())
Notice above that I double escaped the backslash character. This is because the backslash is a special character. When I run the above code, it changed my working directory to ‘C:\Users\Michael\Desktop\’. Also, I am working on a windows 10 computer in case you are using Unix, Linux or Mac.
Creating New Directories with Python
There are occasions you want to create new directories, or what some call make new directories in python. Python can do this very easily when you use the right methods. There are two methods provided in python: the python make directory method, os.mkdir, and the python make directory recursive method, os.makedirs, which acts recursively by creating more than one directory as long as the directories do not already exist.
The syntax of the os.mkdir method is: os.mkdir(path, mode=0o777, *, dir_fd=None)
where path is the name of the directory you want to create. You can leave the other keyword defaults as is because on some systems the mode parameter is just ignored and directory file descriptors, dir_fd, are not implemented.
Supposing we want to create a directory called, new_dir, we could try the following:
import os
try:
os.mkdir('new_dir')
except FileExistsError:
print('Directory already exists.')
else:
print('Directory created successfully.')
I used a try statement to make sure that the directory doesn’t exist before creating it. This is because a FileExistsError is raised if the directory already exists. That gives peace of mind.
The os.makedirs method is also used to create directories but it does this recursively. That means, you can use it to create successive directories. The syntax of the method is: os.makedirs(name, mode=0o777, exist_ok=False)
. Path is the name of the directory you want to create. It has a different argument though from the python make directory method that is worth mentioning. It has an exist_ok keyword argument which you can set to True if you want to create subdirectories of an already existing directory. Let’s use an example:
import os
try:
os.makedirs('new_dir\\second_dir\\third_dir', exist_ok=True)
except FileExistsError:
print('Directory already exists.')
else:
print('Directory created successfully.')
If you run the above on your machine, it creates the directories second_dir and third_dir (remember new_dir has already been created) and prints: ‘Directory created successfully.’ This is because I set the exist_ok argument to True i.e it should create subdirectories even where a directory already exists. The exist_ok argument comes convenient.
How to remove a directory in python
The methods under this category come in handy when you no longer need a directory. You can programmatically remove directories using python with the python remove directory method, os.rmdir, and the python remove directory recursive method, os.removedirs. The latter removes directories recursively. I didn’t tell you in the earlier post on file handling, but you can also remove files if you want to using the python remove file method, os.remove. I will describe all three here.
To remove a single directory, you use the python remove directory, os.rmdir, method. The syntax of the method is: os.rmdir(path, *, dir_fd=None). Path is the name of the directory you want to remove. With this method, you cannot remove directory trees or directories that are not empty otherwise it will raise OSError exception. If the directory does not exist, it will raise a FileNotFoundError.
When I wanted to remove the new_dir created earlier with child directories like this:
import os
try:
os.rmdir('new_dir')
except OSError:
print('Directory not empty.')
else:
print('Directory successfully removed.')
It printed out: ‘Directory not empty.’ That means I cannot remove a directory with child directories using this method. Not to worry, the second method, the python remove directory recursive method can do that: os.removedirs
The syntax of the os.removedirs method is: os.removedirs(name)
where name is the name of the directory you want to remove.
In the example below, I wanted to remove all the directories and sub-directories we created when making directories.
import os
try:
os.removedirs('new_dir\\second_dir\\third_dir')
except OSError:
print('Directory not empty.')
else:
print('Directory successfully removed.')
It ran successfully and printed: ‘Directory successfully removed.’ To ensure it doesn’t raise an OSError exception, you should make sure that the leaf directory, third_dir, is empty i.e it doesn’t contain any files.
Now, let’s show the bonus method on how to remove a file.
The method for removing files is the python remove file, os.remove, method. The syntax is: os.remove(path, *, dir_fd=None)
. Path is the name of the file. If the file is already in use, the method raises an error. Note that the file name, path, should be relative to the current working directory.
In this example here, I want to remove a file that was used when we discussed the file handling methods in an earlier post:
import os
os.remove('eba.txt')
if os.path.isfile('eba.txt'):
print('File not removed.')
else:
print('File removed.')
It ran successfully and printed: ‘File removed.’
How to rename a directory
We can programmatically rename a file or directory in python. There are methods for both single file or directory, or multiple files or directories. The python rename method, os.rename, works for single file or directory, while the python rename recursive, os.renames, method works recursively.
The syntax for the os.rename method is: os.rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)
where src means the source file or directory, and dst means the new name you intend to give the source. The dst or new name should not already exist otherwise the operation will raise an OSError exception or that of one of its subclasses depending on the operating system used.
Here is an example of usage:
import os
try:
os.mkdir('new_dir')
print('Directory created successfully.')
print('Now attempting to rename it.')
os.rename('new_dir', 'old_lady')
except FileExistsError:
print('Directory already exists.')
except OSError:
print('Couldn\'t rename the directory.')
else:
print('new_dir changed successfully to old_lady.')
In the example above, I first created a new directory, new_dir, and when it went successfully without raising an error, I then attempted to rename it from new_dir to old_lady. If old_lady already exists, it will raise an OSError exception which I would handle by printing out: ‘Couldn’t rename the directory’ but if it doesn’t exist already, the renaming would run successfully, (which happened) and then print out: ‘new_dir changed successfully to old_lady.’
Now we can do this recursively. What if we create a directory tree with an empty leaf directory. We would have to use the python rename recursive, os.renames, method.
The syntax of the os.renames method is: os.renames(old, new)
where old refers to the old name of the directory or directories and new refers to their new names.
Let’s take an example from above again. This time, we want to rename all the directories and sub-directories.
import os
try:
os.makedirs('new_dir\\second_dir\\third_dir', exist_ok=True)
print('Directories created successfully.')
print('Attempting renaming of the directories created.')
os.renames('new_dir\\second_dir\\third_dir', 'my_first\\my_second\\my_third')
except FileExistsError:
print('Directories already exists.')
except OSError:
print('Couldn\'t rename the directories.')
else:
print('Renamed all three directories recursively.')
From the above, you could see that I first created a directory tree, new_dir\second_dir\third_dir, and when it was created successfully, I tried an attempt at renaming all the directories recursively using a second try statement. If you do not have the necessary permissions to rename the directory, then the operation will fail. But if the permissions are available and the directories exist as stated in the names for the old directory, then they will be renamed and the code will print: ‘Renamed all three directories recursively.’
You can be creative and try out your own examples to see how it will run.
How to list all the files and nested directories of a directory
I am using windows, so Linux or Unix users pardon me if my example is Windows based. If on windows you want to list the contents of a directory, you use the command ‘dir’ on the command line and it gives you a listing. You can do the same with python. Python has two methods for doing so: a python list directory, os.listdir, method and an optimized python scan directory, os.scandir, method.
It is recommended that you use the python scan directory, scandir, method for most cases, but let me show a working example of the python list directory method. The syntax of the python list directory method is: os.listdir(path='.')
where path is the name of the directory whose contents you want to list. The path parameter is optional and where omitted, it defaults to the current working directory. The method returns a list of all the files and directories that are contained in the directory named path.
Here is an example:
import os
dir_list = os.listdir()
for file in dir_list:
if os.path.isfile(file):
print(f'{file} is a file.')
else:
print(f'{file} is a directory.')
The above code first returns a list of all the files and directories in the current working directory as dir_list. Then I iterate through the list in a for loop and print out whether an item is a file or a directory. This gives you a listing that is similar to the windows ‘dir’ command line .
Now, for the optimized python scan directory, scandir, method. The syntax of the optimized scan directory method is os.scandir(path='.')
where path is the name of the directory. Scandir returns an iterator which yields objects that correspond to the files or nested directories in the path name. You can return the object name, whether they are files or directories, from the objects yielded. (If you want a refresher on iterators or on python generators that yields objects then click on the corresponding links.). Having objects that have file types and attributes increases code performance provided the operating system can provide this information.
Since the iterator produced by the python scan directory method is a resource, you need to close it or garbage collect it by calling the close method, scandir.close(), but you could do this better by using a with statement.
In the example below, we will list the contents of the current working directory again, but this time showing how to do it with the python scan directory method working as a generator.
import os
with os.scandir() as my_dir:
for item in my_dir:
if item.is_dir(follow_symlinks=False):
print(f'{item.name} is a directory.')
else:
print(f'{item.name} is a file.')
I used the with statement so that python will automatically close the iterator immediately the operation ends. You will notice that each object, item, yielded also has attributes of their own. In this example, item object has name attribute in item.name, and also the is_dir method in item.is_dir. This is because the objects are os.DirEntry objects. In the item.is_dir method, in order not to follow symbolic links and list a directory having files as a file, I switched the follow_symlinks parameter to False. This makes it possible to accurately get all directory listings.
Now you have been equipped to use python’s directory handling functions. Go experiment with what you can do with them.
Happy pythoning.