The WITH statement and context manager in Python

Source: Internet
Author: User
Using the WITH statement as the context manager object in Python, and the use of the Contextlib module that provides the context manager is an advanced technique in Python programming, let's take a detailed look at the WITH statement in Python and the context Manager learning Summary:

0. About Context Manager
The context manager is an object that can be used in the WITH statement, with the __enter__ and __exit__ methods.

With manager as Var:  Do_something (Var)

is equivalent to simplification in the following cases:

var = manager.__enter__ () Try:  do_something (Var) finally:  manager.__exit__ ()

In other words, the context Manager protocol defined in PEP 343 allows the boring try...except...finally structure to be abstracted into a single class, leaving only the do_something part of the concern.

The __enter__ method is called first. It can return the value assigned to Var. The as section is optional: If it does not appear, the return value of enter is simply ignored.
The code under the WITH statement is executed. Just like a try clause, they either execute successfully to the end, or break,continue or return, or can throw an exception. In either case, after the block is over, the __exit__ method is called. If an exception is thrown, the exception information is passed to __exit__, which is discussed in the next section. Typically, exceptions can be ignored, as in the finally clause, and will be re-thrown after the __exit__ ends.
For example, we want to make sure that a file is closed immediately after the write operation is completed:

>>> class closing (object): ...  def __init__ (self, obj): ...   Self.obj = obj  ... def __enter__ (self): ...   Return self.obj  ... def __exit__ (self, *args): ...   Self.obj.close () >>> with closing (open ('/tmp/file ', ' W ')) as F:  ... F.write (' The contents\n ')

Here we ensure that f.close () is called when the With block exits. Because closing a file is a very common operation, the support already appears in the file class. It has a __exit__ method called close, and itself can be used as the context manager.

>>> with open ('/tmp/file ', ' a ') as F:  ... F.write (' more contents\n ')

The common use of try...finally is to release resources. The different situations are similar: resources are obtained in the __enter__ phase, released in the __exit__ phase, and passed if an exception is thrown. As with file operations, this is often a natural operation after the object is used, and built-in support makes it easy. Every version, Python is supported in more places.

1. How to use the context Manager:

How to open a file and write "Hello World"

Filename= "My.txt" mode= "W" Writer=open (filename,mode) writer.write ("Hello World") writer.close ()

When an exception occurs (such as when the disk is full), there is no opportunity to execute line 5th. Of course, we can use the try-finally statement block to wrap:

Writer=open (Filename,mode) Try:  writer.write ("Hello World") finally:  Writer.close ()

When we do complex operations, the try-finally statement becomes ugly and is rewritten with a with statement:

With open (Filename,mode) as Writer:  writer.write ("Hello World")

As refers to the content returned from the open () function and assigns it to the new value. With completed the try-finally task.

2. Custom Context Manager

The With statement acts like try-finally, providing a context mechanism. To apply a class with a statement, the internal must provide two built-in functions __enter__ and __exit__. The former executes before the principal code executes, and the latter executes after the principal code executes. The variables following the as are returned in the __ENTER__ function.

Class Echo ():  def output (self):    print ' Hello World '  def __enter__ (self):    print "Enter"    return Self #可以返回任何希望返回的东西  def __exit__ (self,exception_type,value,trackback):    print "Exit"    if exception_type= =valueerror:      return True    else:      return flase >>>with Echo as E:  e.output ()


Output:

Enterhello Worldexit

The complete __exit__ function is as follows:

def __exit__ (SELF,EXC_TYPE,EXC_VALUE,EXC_TB)

Where Exc_type: Exception type; Exc_value: Exception value; EXC_TB: Exception tracking information

When __exit__ returns True, the exception is not propagated

3. Contextlib Module

The role of the Contextlib module is to provide an easier-to-use Context Manager, which is implemented through generator. The ContextManager in Contextlib is used as an adorner to provide a context-management mechanism for function-level, commonly used frameworks such as:

From contextlib import Contextmanager@contextmanagerdef make_context ():  print ' Enter '  try:    yield "OK"  except Runtimeerror,err:    print ' error ', err  finally:    print ' exit '    >>>with Make_ Context () as value:  Print value


The output is:

  Enter  OK  exit

Where yield is written in try-finally to ensure that the value of the variable after the as of exception security (capable of handling exceptions) is returned by yield. The statement preceding the yield can be thought of as a pre-operation of the code block, and the operation after yield is considered an operation in the __EXIT__ function.

Take the thread lock as an example:

@contextlib. Contextmanagerdef loudlock ():  print ' Locking '  lock.acquire ()  yield  print ' releasing '  lock.release () with Loudlock ():  print ' lock was locked:%s '% lock.locked ()  print ' Doing something that needs Locking ' #Output: #Locking #lock is locked:true#doing something that needs locking#releasing

4. contextlib.nested: Reduce nesting

For:

With open (Filename,mode) as reader: with  open (Filename1,mode1) as Writer:    Writer.write (Reader.read ())

can be simplified by contextlib.nested:

With contextlib.nested (open (Filename,mode), open (Filename1,mode1)) as (Reader,writer):  writer.write ( Reader.read ())

In Python 2.7 and later, it is replaced by a new syntax:

With open (Filename,mode) as Reader,open (Filename1,mode1) as Writer:  Writer.write (Reader.read ())

5, Contextlib.closing ()

The file class directly supports the context Manager API, but some objects that represent open handles are not supported, such as the object returned by Urllib.urlopen (). There are also legacy classes that use the close () method and do not support the context Manager API. To ensure that the handle is closed, you need to use closing () to create a context manager for it (call the Close method of the Class).

Import Contextlibclass MyClass ():  def __init__ (self):    print ' __init__ '  def close (self):    print ' close () ' With   contextlib.closing (MyClass ()):  print ' OK '


Output:

__init__okclose ()


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.