Python context manager and with block details,
The content of the context manager and with block is as follows:
The context manager object is used to manage with statements, just as the iterator is used to manage for statements.
The with Statement aims to simplify the try/finally mode. This mode is used to ensure that an operation is executed after a piece of code is run. Even if the code is aborted due to an exception, return statement, or sys. exit () call, the specified operation is executed. The code in the finally clause is usually used to release important resources or restore the status of temporary changes.
= The context manager protocol includes two methods: enter and exit =. When the with statement starts to run, the enter method is called on the context manager object. After the with statement is run, the exit method is called on the context manager object to assume the role of the finally clause.
= The result of executing the expression after with is the context manager object. binding the value to the target variable (as Clause) is the result of calling the enter method on the context manager object =. The as clause of the with statement is optional. For open functions, the as clause must be added to obtain file references. However, some context managers return None because there are no useful objects available to users.
with open('mirror.py') as fp: ...
Custom context class:
class A: def __init__(self, name): self.name = name def __enter__(self): print('enter') return self.name def __exit__(self, exc_type, exc_val, exc_tb): print('gone')with A('xiaozhe') as dt: print(dt)
Contextlib Module
The contextlib module also has some classes and other functions, which are widely used.
Closing: if the object provides the close () method but does not implement the enter/exit protocol, you can use this function to build the context manager.
Suppress: Build a context manager that temporarily ignores the specified exception.
@ Contextmanager: = This decorator converts a simple generator function into a context manager =, so that you do not need to create a class to implement the manager protocol.
ContextDecorator: This is a base class used to define a class-based context manager. This context manager can also be used to decorate functions and run the entire function in a managed context.
ExitStack: the context manager can access multiple context managers. At the end of the with block, ExitStack calls the exit method of each context manager in the stack in the order of first-in-first-out.
= @ Contextmanager is the most widely used decorator, so pay special attention to it. This decorator is also confusing because it has nothing to do with iteration, but yield Statement = is used.
Use @ contextmanager
@ Contextmanager the modifier can reduce the amount of sample code for creating the context manager. Instead of writing a complete class definition enter and exit methods, you only need to implement a yield statement generator, generate the value to be returned by the enter method.
In the generator decorated with @ contextmanager, the yield statement is used to divide the definition body of a function into two parts: = all the code before the yield statement is executed at the beginning of the with block (that is, when the interpreter calls the enter method, the code after the yield statement is executed = at the end of the with block (that is, when the exit method is called.
import contextlib@contextlib.contextmanagerdef test(name): print('start') yield name print('end')with test('zhexiao123') as dt: print(dt) print('doing something')
Implementation Principle
The contextlib. contextmanager annotator packs functions into classes that implement the enter and exit methods. The class name is _ GeneratorContextManager.
The enter method of this class has the following functions:
1. Call the generator function to save the generator object (called gen here ).
2. Call next (gen) and execute it to the location where the yield keyword is located.
3. Return the output value of next (gen) to bind the output value to the target variable in the with/as statement.
When the with block is terminated, the exit method will do the following:
1. Check whether the exception is passed to exc_type. If yes, call gen. throw (exception) and throw an exception in the row containing the yield keyword in the generator Function Definition body.
2. Otherwise, call next (gen) to continue executing the code after the yield statement in the generator Function Definition body.
Exception Handling
To tell the interpreter that the exception has been handled, the exit method returns True, and the interpreter will suppress the exception. If the exit method does not explicitly return a value, the interpreter obtains None and then bubbles up.
When @ contextmanager is used, the default behavior is the opposite: the exit method provided by the decorator assumes that all exceptions sent to the generator are handled, so the exception should be suppressed. If you do not want @ contextmanager to suppress an exception, you must explicitly re-Throw the exception in the decorated function.
The above code has a bug: if an exception is thrown in the with block, the Python interpreter will capture it and then throw it again in the yield expression of the test function. However, there is no code to handle the error, so the test function will stop.
When using the @ contextmanager modifier, place the yield statement in the try/finally statement, because we never know what the following manager users will do in the with block.
import contextlib@contextlib.contextmanagerdef test(name): print('start') try: yield name except: raise ValueError('error') finally: print('end')with test('zhexiao123') as dt: print(dt) print('doing something')
The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.