In this post, I will discuss the python syntax with
. We can use this syntax in exception handling to make the code cleaner and much more readable. It simplifies the management of common resources like file streams.
In python, we can use try
and except
as follows:
1 | try: # Try to do something |
For example:
1 | try: |
We can use a shorter code to the exact same thing:
1 | with open('aFile.txt') as f: |
As we can see, with
can make the code shorter.
To use with
in python, there are some definitions to understand:
Context Management Protocol
Context Management Protocol contains two methods: .__enter__()
and .__exit__()
. The former (.__enter__()
method) is to allocate resource, while the latter (.__exit__()
method) is to free the resource.
An object with these two methods can be processed by with
.
Context Manager
An object with methods .__enter__()
and .__exit__()
is called context manager. For this example, the output of open('aFile.txt')
(which is an object) is the context manager.
Context Expression
The syntax after with
is called context expression. This syntax should return a context manager. For this example, open('aFile.txt')
is a context expression.
With-body
The syntaxes wrapped up by with
syntax are called with-body. For this example, data = f.read()
is the with-body.
The standard format of with
syntax is as follows:
1 | with conetext_expression [as target(s)]: |
Then the process of with
syntax is:
- Execute
.__enter__()
method, the output of this method will be assigned to variabletarget
. - Execute with-body syntaxes.
- Execute
.__exit__()
method.
An example can be seen as follows:
1 | class Manager: |
If we execute the with
code as follows:
1 | with Manager('Amy') as test: |
The output is as follows:
1 | [Enter Amy]: Allocate resource. |
If any exception raises, we can simulate this situation with code as follows:
1 | with Manager('Amy') as test: |
The output is as follows:
1 | [Enter Amy]: Allocate resource. |
Module contextlib
provided three objects, contextmanager
, function nested()
and closing
. I will focus on nested()
here.
Function nested()
can organize many Context Managers together without nested syntaxes.
See this example:
1 | with nested(A(), B(), C()) as (X, Y, Z): |
This is the same as:
1 | with A() as X: |