Create Customized Context Manager for Python With Statement: A Completed Guide – Python Tutorial

By | December 12, 2019

Python with statement allows us to use a context manager to manage a block of python code. However, how to create a customized context manager for python with statement? In this tutorial, we will discuss this topic.

To create a context manger for python with statement is simple, we will give you a simple python template.

Python context manager code template

Here is code template.

class Mycontex(object):
    def __init__(self, name):
        print("context manager is initialized")
        self.name=name
    def __enter__(self):
        print("enter context manager")
        return self
    def do_self(self):
        print(self.name)
    def __exit__(self,types, value, traceback):
        print("exit context manager")
        print(types)
        print(value)
        print(traceback)

If you plan to create a customized context manager, you should realize these methods:

__init__(): this method is called when a context manager object is initialized.

__enter__(): this method is called when you open a context manager object.

__exit__(): this method is called before a context manager is finished.

As to __exit__(), the parameters (types, value, traceback) are:

First of all, if a context manager does not raise any excepitons, types, value, traceback will be None.

However, if there is any exceptions raised by it, types, value, traceback will be:

types: the type of exception

value: the description of this exception

traceback: where the exception is raised.

We will use some example to illustrate all above.

As to a basic context manager

if __name__ == '__main__':
    with Mycontex('context manager') as mc:
        print(type(mc))
        mc.do_self()

The result will be:

context manager is initialized
enter context manager
<class '__main__.Mycontex'>
context manager
exit context manager
None
None
None

From the result, we can find:

1. when run Mycontex(‘context manager’), __init__() is called, which will 0utput context manager is initialized

2. when with Mycontex(‘context manager’) as mc, __enter__() is called, which will output enter context manager. You may find this function returns an object, this object will be save in mc.

In this example, the type of mc is: <class ‘__main__.Mycontex’>

If you change __enter__() to:

    def __enter__(self):
        print("enter context manager")
        f = open("data.txt")
        return f

This function return a <class ‘_io.TextIOWrapper’> object, mc will be <class ‘_io.TextIOWrapper’>.

3.After we have called mc.do_self(), this context manager will be finished. __exit__() will be called, which will output exit context manager. Because of no exception is raised, types, value and traceback are None.

How about exception is raised in context manager?

If we edit do_self() to be:

    def do_self(self):
        print(1/0)
        print(self.name)

This function will raise an exception. Run this code again, we will get result:

context manager is initialized
enter context manager
<class '__main__.Mycontex'>
exit context manager
<class 'ZeroDivisionError'>
division by zero
<traceback object at 0x000001DA7C8314C8>
Traceback (most recent call last):
  File "E:\workspace-nlp\Example\amod-test.py", line 22, in <module>
    mc.do_self()
  File "E:\workspace-nlp\Example\amod-test.py", line 10, in do_self
    print(1/0)
ZeroDivisionError: division by zero

Then we will find: When an exception occurs, __exit__() will be called.

At that moment, types, value and traceback will be:

types: exception type, <class ‘ZeroDivisionError’>

value: exception description, division by zero

traceback: where exception occur in, <traceback object at 0x000001DA7C8314C8>

Leave a Reply