Detailed information about the Python context manager and with blocks

Source: Internet
Author: User
This article mainly for you in detail the Python context Manager and with the relevant data, with a certain reference value, interested in small partners can refer to

Context Manager and with blocks, as follows

The purpose of the context Manager object is to manage the WITH statement, just as the iterator exists to manage the for statement.

The WITH statement is designed to simplify the try/finally pattern. This mode is used to ensure that an operation is performed after a piece of code has been run, even if that code is aborted due to an exception, return statement, or Sys.exit () call, and the specified action is performed. The code in the finally clause is typically used to release important resources, or to restore the state of a temporary change.

= = The Context Manager protocol contains the Enter and exit two methods = =. When the With statement starts running, the Enter method is called on the context manager object. When the WITH statement finishes running, the exit method is called on the context Manager object to play the role of the finally clause.

= = The result of executing the expression with the following is the context Manager object, which binds the value to the target variable (as clause) is the result of the call to the Enter method on the context Manager Object = =. The AS clause of the WITH statement is optional. For the open function, you must add the AS clause to get a reference to the file. However, some context managers return None because there are no useful objects that can be provided to the user.


With open (' mirror.py ') as FP:  ...

Custom Context Classes:


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

There are also classes and other functions in the Contextlib module that are used more broadly.

Closing: If the object provides a close () method, but does not implement the enter/exit protocol, you can use this function to build the context manager.
Suppress: Constructs a context manager that temporarily ignores the specified exception.
@contextmanager: = = This adorner turns a simple generator function into a context manager = =, so that you don't have to create a class to implement the manager protocol.
Contextdecorator: This is a base class that defines a class-based context manager. This context manager can also be used for decorating functions that run the entire function in a managed context
Exitstack: This context Manager can enter multiple context managers. At the end of the With block, the Exitstack calls the exit method of each context manager in the stack in a last-in, first-out order.

= = The most widely used is the @contextmanager adorner, so be extra careful. This adorner also has a confusing side, because it has nothing to do with iteration, but uses the yield statement = =.

Using @contextmanager

@contextmanager adorners Reduce the amount of boilerplate code that creates a context manager without writing a complete class definition of the Enter and exit methods, and simply implement a generator with a yield statement to generate the values that you want the Enter method to return.

In a builder that uses @contextmanager decorations, the yield statement divides the definition of the function into two parts: all the code in front of the ==yield statement executes at the start of the With block (that is, when the interpreter calls the Enter method), and the code behind the yield statement is in the wit When the H block ends (that is, when the exit method is called) = = is executed.


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 adorner wraps the function into a class that implements the Enter and exit methods. The name of the class is _generatorcontextmanager.

The Enter method for this class has the following effect:
1. Call the generator function to save the generator object (referred to here as Gen).
2. Call Next (gen) and execute to the location where the yield keyword is located.
3. Return the value of next (gen) output to bind the output value to the target variable in the With/as statement.

When the With block terminates, the exit method does several things:

1. Check that the exception is passed to Exc_type; if there is, call Gen.throw (Exception), the line that contains the yield keyword in the generator function definition body throws an exception.
2. Otherwise, call next (gen) to continue executing the code after the yield statement in the body of the generator function definition.

Exception handling

To tell the interpreter that the exception has been handled, the Exit method returns True, at which point the interpreter suppresses the exception. If the exit method does not explicitly return a value, the interpreter gets none and then bubbles up the exception.

When using the @contextmanager adorner, the default behavior is reversed: The Exit method provided by the adorner assumes that all exceptions to the generator are handled, so the exception should be suppressed. If you do not want the @contextmanager to suppress the exception, you must explicitly re-throw the exception in the decorated function.

The code above has a bug: If an exception is thrown in the With block, the Python interpreter captures it and then throws it again in the yield expression of the test function. However, there is no code to handle the error, so the test function aborts.

When using the @contextmanager adorner, place the yield statement in the try/finally statement because we never know what the user of the context manager 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 ')
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.