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>