Delving into Python Decorators: Part 4

Ashwin Nair
Analytics Vidhya
Published in
5 min readAug 12, 2020

--

This is the final part of the four-part series on decorators in Python. Part one, part two, and part three can be found here.

In part one, we discussed how decorators work, along with when and why to use them. In part two, we covered how to use decorators as a basic way of debugging functions, and in part three, we used decorators to rate-limit (or slow down) functions.

In this article, we’re going to review how Python uses decorators in the standard library. We will be reviewing the module contextlib[1], from the Python standard library. The contextlib module has a few functionalities, but we will be using it to build a context manager[2]. First, review the code below:

A basic file opening and closing.

This code block opens the text_file file, reads from it, and then closes it. Closing a resource is important because failing to do so leads to memory leakage[3]. Memory leaks are encountered in Python in a few different ways, but the method we will discuss in this article is going to be opening a file and not closing it afterward. By forgetting to do this, you cause a memory leak. That's why so many programmers use the with keyword since it automatically closes the file after it's done, and frees up the resources it was using. It's important to remember that the with keyword is an example of a context manager. It is used to manage resources when opening a file. See below:

Using with to automatically open and close a file.

This is a more efficient way to read a file since you don’t have to manually close it every time. However, this can be further improved. We can use contextlib to build a custom context manager. See below:

Our custom context manager, ready to use.

As done in previous parts, let’s break this down into simpler steps.

Step 1: Import statements

We only have 2 modules we’re importing from: colorama and contextlib.

colorama makes terminal output colorful, and it requires a pip install if you have not installed it before. To do so, type pip3 install colorama in your terminal. If you've been following along with the series, you probably have colorama installed from the previous decorator articles.

Step 2: context_manager Decorator

The context_manager decorator turns the decorated function into a context manager, as seen with the my_file_manager function. contextlib uses this to notify Python that this is a context manager, so without this, you would get an error that says that the context manager does not implement an __enter__[4] or __exit__[5] method. These two methods are integral to creating a context manager, and the contextlib module includes them in the decorated function.

Step 3: Inside my_file_manager

This context manager has multiple uses. You can use it to read from, write to, and append to files. Today we will be using the write and read functions. The mode is passed through the arguments for my_file_manager function, and it is used to determine the value of a variable called type_mode. This variable elaborates on what the my_file_manager function is currently doing and then is used in the final print statement, to show what the function is actually doing. We use a try/finally[6] block, within which we have a yield[7] statement. The yield statement is usually used to return a sequence of values - so it doesn't quit the function after returning a value, whereas the return statement returns a singular value and quits the function. We use the yield statement because we have more code after it, so we need to come back to the my_file_manager function. Moving onto the finally block, we have a print statement showing what operation was performed, and the file closing statement.

Step 4: Using the context manager

Now, we can use our context manager to interact with text files.

First, let’s look at how the file manager handles writing to a file. We can make a simple with statement using our context manager to write to a text file.

A small “with” statement that writes (and creates the file if it doesn’t exist yet) to a file.

Our terminal output:

By executing this block of code, you should see a new text file in your current working directory called ‘text-file.txt’. If you open it, you see whatever you set as your output_string variable.

Now, let’s look at reading from a text file.

A small with statement for reading from a text file.

This with statement reads the contents of the previously created text-file.txt file. It then prints out the text in the file, which was also created with the previous statement. Now for our terminal output:

Great, it works!

In short, we’ve successfully read from a text file, using our own custom file manager. This file manager is scalable and can be changed to work with a database, or other resources. We learned how Python uses decorators to make context managers with the contextlib module. We worked a bit more with colorama and found another use for decorators in Python.

If you’ve been following along with this series, you’ve learned a good amount of material about Python decorators. In article one, we learned how to use decorators in our code. In article two, we built a basic logging function, used to see how long it took for the decorated function to run while learning about the colorama and time modules from the standard library. In article three, we used decorators to slow down (or rate-limit) code, along with utilizing the random, funcTools, and sys modules from the standard library. In this article, we used decorators to create a context manager, while using the contextlib module. Pat yourself on the back for delving deeper into one of Python’s most helpful features.w

Thanks for reading, and I hope you’ve enjoyed reading this series as much as I enjoyed writing it. If you’ve enjoyed my writing, please consider subscribing so you can see my new series as soon as they’re out.

--

--

Ashwin Nair
Analytics Vidhya

Pursuing my bachelors in Computer Science, while learning Natural Language Processing with SpaCy and Python.