Introduction to Python Contextlib
Contextlib is a Python module that contains context manager utilities that work for context managers and the “with” statement. In Python, the allocation and releasing or resource management is done using context manager using the “with” statement. This “with” keyword is used because it automatically closes any file that is open and releases the resources. Contextlib is one of the whole standard library modules that contains tools for creating and works similar to the context manager class, which uses @contextmanager as a decorator. This is one of the shortcut methods for creating context managers.
Examples of Contextlib Module
A context manager is created or implemented using two methods in the class, and they are __enter__() method and __exit__()method. In this library module, the __enter__() method will be defined as the decorator of the library is used in the generator function that calls the yield statement exactly once. So the statements before the yield statements or statements before the call to yield are considered as the code for the __enter__() method. The statements after the yield statements or statements after the call to yield statement are considered as the code for the __exit__ ()method.
1. contextmanager decorator
Now we can create a context manager using __enter__() and __exit__() methods is not much difficult, but it is more overhead sometimes. So we can use the @contextmanager decorator to convert generator functions into a context manager.
Code:
from contextlib import contextmanager
@contextmanager
def open_file(path, mode):
the_file = open(path, mode)
yield the_file
the_file.close()
files = []
for x in range(100000):
with open_file('foo.txt', 'w') as infile:
infile.write('Hello Educba')
for f in files:
if not f.closed:
print('not closed')
files =open('foo.txt', 'r+')
contents = files.read()
print(contents)
Output:
The above code implementation is shorter when compared to creating a class for context manager. It is just as to open a file, yield the contents, and close it. As we are using with the statement here again, in fact, all the files are indeed closed in this above code.
2. Nested Implementation
So many times, it is needed to maintain multiple contexts simultaneously. This process can be done by nesting with statements one inside another. There is a method called nested() which nests the context using a single with statement.
Code:
import contextlib
@contextlib.contextmanager
def multicontext(ctxt):
print 'entering contents:', ctxt
yield ctxt
print 'exiting contents:', ctxt
with contextlib.nested(multicontext('Educaba'), multicontext('Training'), multicontext('Intitute')) as (X, Y, Z):
print 'inside with statement:', X, Y, Z
Output:
In the above code, the nested() method is used to print the multiple contents; this method returns the result of the contents in reverse order, as we can see in the output. The contextlib library module was used in earlier versions of Python. As Python 2.7 and later versions, the working of the nested() method is now done using a statement only. So without the nested() method, the example is modified as below:
Code:
import contextlib
@contextlib.contextmanager
def multicontext(ctxt):
print 'entering contents:', ctxt
yield ctxt
print 'exiting contents:', ctxt
with multicontext('Educba') as X, multicontext('Training') as Y, multicontext('Institute') as Z:
print 'inside with statement:', X, Y, Z
Output:
So we can see its results are the same as the previous code output using the nested() method.
3. Class-based approach for using contextlib
contextlib.ContextDecorator is used to define the context managers using a class-based approach. By using this, it can be used as a normal function or as a function decorator. Let’s take an example for it:
Code:
from contextlib import ContextDecorator
class htmlparagraph(ContextDecorator):
def __enter__(self):
print('<p>')
return self
def __exit__(self, *exc):
print('</p>')
return False
@htmlparagraph()
def emit_html():
print('Here is some non-HTML ')
emit_html()
Output:
4. Closing open handles
There are many classes to close these files or handlers like a close() method, but the context manager API does not support this, so there is another method called closing() which is used as a closing () method in context managers. Let’s see the example of how the closing() method is used:
Code:
import contextlib
class contxt(object):
def __init__(self):
print 'inside the init() method'
def close(self):
print 'inside the close() method'
with contextlib.closing(contxt()) as ctxt:
print 'inside the with statement'
print
print 'Error handling:'
try:
with contextlib.closing(contxt()) as ctxt:
print ' raising from inside the with statement'
raise RuntimeError('There is a runtime error')
except Exception, err:
print ' Had an error:', err
Output:
The above code is closed irrespective of whether there is an error or not in with a statement.
Conclusion
In this article, we have discussed how the context manager can be created not and only using classes, but also there is another shortcut method in Python known as contextlib. This is the Pythons standard library for creating and working of context managers similar to declaring classes. In this library, there are other sub-modules used such as contextmanager for creating context managers using with statement, which has nested() method to release the multiple contexts, but this method is depreciated from Python 2.7 and later versions because the working of this nested() method is now done by with statement itself. There is another method used with this module is a closing() method, which helps you close the files or handler irrespective of errors in with statements that are handled by the exceptions.
Recommended Articles
This is a guide to Python Contextlib. Here we discuss the basic concept of creating a context manager and implementing the Contextlib Module with its examples. You may also have a look at the following articles to learn more –
24 Online Courses | 14 Hands-on Projects | 110+ Hours | Verifiable Certificate of Completion
4.8
View Course
Related Courses