Python--with Statement, Context Manager type, and Contextlib library

Source: Internet
Author: User

Directory

One, with statements

Second, context Manager

Three, Contextlib module

One, with statements

Detailed description of the WITH statement in Python: PEP 343

The WITH statement wraps the execution of a piece of code with a method defined by the context Manager, equivalent to a simple version of the try... except... finally statement. The main context of the WITH statement: Regardless of whether the execution of a block of code has an exception, perform some actions (such as cleanup) at the end.

With statement syntax:

WITH_STMT:: =  "with" With_item ("," With_item) * ":" Suitewith_item:: =  expression ["as" target]

Or:

with expression [as variable]:    with-block

Expression should return an object that supports the context management protocol, and if the AS clause exists, the return value of the object will be assigned to the variable name following the AS.

The first syntax represents the execution flow of the WITH statement in:

    1. Evaluates the context expression (the expression given in With_item ) and obtains a context manager that includes the __enter__ () and __exit__ () methods;
    2. The __exit__ () method that loads the context manager is reserved for later use;
    3. Invokes the __enter__ () method of the context manager;
    4. If the With_item in the WITH statement specifies the target alias (the variable name after the AS clause), the return value of__enter__ () is assigned to the target alias;

  * Note

The WITH statement ensures that __exit__ () must be called as long as __enter__ () returns normally. Therefore, if an error occurs when assigning a value to the target alias, the error will be treated as if it occurred in the suite. You can look at the 6th step below.

5. The suite part that is nested within the WITH statement is executed (the With-block part of the second representation);

6. The __exit__ () method of the context manager is called, and if an exception causes the suite (With-block) part to exit, the type, value, and backtracking of the exception are passed as parameters to __exit__ (type value, Traceback) method, the three values are the same as the return values of the Sys.exc_info. If the Suite (with-block) section does not throw an exception, the three parameters of __exit__ () are none.

If the suite part is exited due to an exception, and the return value of the __exit__ () method is False, the exception is lifted, and if the return value is true, the exception is terminated and the code after the WITH statement continues execution.

If the suite part is exited because it is not an exception, thereturn value of the __exit__ () method is ignored, and execution continues where the exit occurred .

  Example of a single context manager:

With open (R ' C:\misc\data ') as myfile: For line in    myfile:        print (line) ... more        code ...

The file object in Python contains the context manager that automatically closes the file object after the with code snippet, so even if an exception is thrown in the for loop that handles the file object, the object referenced by MyFile is guaranteed to shut down gracefully.

  

Multiple context managers are handled in the same way as multiple with statements nested execution:

With a () as a, B () as B:    Suite

Equivalent to:

With a () as a: with    B () as B:        Suite

  Multiple Context Manager Examples:

With open (' data ') as FIN, open ("Res ', ' W ') as Fout: For line in    fin:        if ' some key ' in line:            Fout.write (line)

  

Ii. Context Manager type
Context Manager is an object in Python that defines the runtime context when executed with statements, which control the functionality of the in/out runtime context, which is usually triggered by the with statement, or directly by invoking their methods to make with them.

The general usage of the context Manager includes saving and restoring a wide variety of global states, unlocking resources, closing open files, and so on.

Some of the built-in Python types have context managers, such as file objects, but we can also implement the context manager we need, and the context manager must provide the following two methods:

object. __enter__ (self)

Enters the runtime context of object-dependent, and if there is an as clause, the WITH statement binds the return value of the method to the target (alias) specified by the AS clause.

object. __exit__ (Self, Exc_type, Exc_value, Traceback)

exits the object-dependent run-time context, which describes the exception that caused the context to exit, and if the context exits without an exception, three parameters 's All None.

If an exception is provided in the parameter, and the method wants to suppress the exception (such as preventing it from propagating), then it should return a true value, otherwise the function will normally handle the exception when it exits.

the __exit__ () method should not re-throw the passed-in exception, which is the function of calling __exit__ ()

  

The python with statement supports the concept of a run-time context defined by the context Manager, implemented by two methods that allow the user to define the runtime context in a custom class, and the execution process enters the context before the With statement begins and exits when the With statement ends.

To define a run-time context, the context manager must provide a pair of methods:

ContextManager. __enter__ ()

Enters the runtime context, either returns the object or returns an object associated with the run-time upper bound, and, if there is an as clause, binds the return value of the method with the target (alias) specified by the AS clause.

For example, the file object returns itself in __enter__ () so that the open () function can be used as an environment expression in a with statement.

In another case, Decimal.localcontext () returns a related object. The context Manager sets the active decimal context to the copy of the initial decimal context, and then returns the copied reference. This allows you to modify the current decimal context in the WITH statement without affecting the code outside the With statement.
ContextManager. __exit__ (Exc_type, Exc_val, EXC_TB)
Exits the run-time context, returning a bool-type identity indicating whether an exception should be suppressed, the argument describing the exception that caused the context to exit, and if the context does not exit because of an exception, then three parameters are none.
If this method returns True, it causes the WITH statement to suppress the exception, and then executes the statement immediately after the WITH statement, otherwise the exception propagates normally after the method call ends, and the exception that occurs when the method executes overrides all other exceptions that occur when the WITH statement is executed.
The incoming exception should not be explicitly re-lifted, but should return false to indicate that the method has been executed properly and does not suppress the incoming exception, which makes it easier for the context Manager to detect whether the __exit__ () method is actually failing to execute.
Python defines a number of context managers, Python's generator type and adorner Contextlib.contextmanager provide the means to implement the context Manager protocol, If a generator function is decorated by the adorner Contextlib.contextmanager, it will return a context manager that implements the necessary __enter__ () and __exit__ () methods Instead of an ordinary iterator.

Note that there is no specific slots for any of these methods in the type structure for Python objects in the python/c API. Extension types wanting to define these methods must provide them as a normal Python accessible method. Compared to the overhead of setting up the runtime context, the overhead of a single class dictionary lookup is negligible .

Example of a custom context manager:

Class TraceBlock (object):    def message (self, arg):        print (' running ' + arg)    def __enter__ (self):        print ( ' Starting with block '        return to self    def __exit__ (self, exc_type, Exc_value, EXC_TB):        if Exc_type is None:            print (' exited normally\n ')        else:            print (' Raise an exception! ' + str (exc_type))            return False #Propagateif __name__ = = ' __main__ ': With    TraceBlock () as Action:        Action.message (' test1 ')        print (' reached ') with     TraceBlock () as Action:        action.message (' test2 ')        Raise TypeError        print (' not reached ')

  

Three, Contextlib module

The module provides support for the WITH statement, which provides the following functions:

Contextlib.contextmanager (func)

Adorner, which defines a factory function of the context manager of a with statement without having to create a class or specify the __enter__ () and __exit__ () methods separately.

  Example

(This example should not be used to actually generate html! ):

From contextlib import contextmanager@contextmanagerdef tag (name):    print "<%s>"% name    yield    print " </%s> "% name>>> with tag (" H1 "): ...    Print "foo" ...

A builder-iterator must be returned when the decorated function is called. The iterator produces a value each time, and if there is an as clause, this value is used to bind to the AS clause in the WITH statement

Where the generator yields, the code block nested within the WITH statement (With-block) is executed, and the generator continues execution after the code block exits, and if there is any exception thrown in the code block that is not handled, it will be lifted in the generator, so you can use the try ... except... finally statement to handle the error, or to ensure that some cleanup work is done. If the goal of catching an exception is to log or perform some action (rather than suppress it), the generator must re-raise the exception. Otherwise, the generator context Manager will tell the WITH statement that the exception has been handled, but once the code is executed into the WITH statement, the exception will continue immediately.

contextlib.closing (thing)

Returns a context manager that closes the parameter thing when execution of a code block is completed . equivalent to:

From Contextlib import contextmanager@contextmanagerdef closing (thing):    try:        yield thing    finally:        Thing.close ()

You can use this:

From Contextlib import closingimport urllibwith closing (urllib.urlopen (' http://www.python.org ')) as page: for line    In page:        print Line

In this example, you do not have to explicitly close the page. Even if an error occurs, the page.close () is executed when the with code block exits

Python--with Statement, Context Manager type, and Contextlib library

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.