Python with statements in detail

Source: Internet
Author: User
First, Introduction

With is a new syntax introduced from Python 2.5, more precisely, a contextual management protocol that simplifies the process of try...except...finally. With is initialized by the __enter__ method, and then the __exit__ is done and the exception is handled. With some tasks that need to be pre-set and cleaned up afterwards, with provides a very handy expression.

The basic syntax for with is as follows, expr is an arbitrary expression, VAR is a single variable (can be a tuple), and "as VAR" is optional.
Copy the Code code as follows:


With EXPR as VAR:
BLOCK


According to Pep 343 's explanation, with...as ... will be translated into the following statement:
Copy CodeThe code is as follows:


MGR = (EXPR)
Exit = Type (MGR). __exit__ # not calling it yet
Value = Type (MGR). __enter__ (MGR)
EXC = True
Try
Try
var = value # only if "as VAR" is present
BLOCK
Except
# The exceptional case was handled here
EXC = False
If not exit (Mgr, *sys.exc_info ()):
Raise
# The exception is swallowed if Exit () returns True
Finally
# The normal and Non-local-goto cases is handled here
If exc:
Exit (Mgr, none, none, none)


Why is it so complicated? Note that the code in the finally does not perform a finally cleanup until the block is executed, because when expr executes, an exception is thrown, and access to Mgr.exit execution will report attributeerror error.


Ii. means of realization

As you can see from the front facing with translation, the object that is evaluated by with must have a __enter__ method and a __exit__ method. Take a look at a file read example, notice here we have to solve 2 problems: File read exception, after reading, close the file handle. This is usually written in try...except:
Copy the Code code as follows:


f = open ('/tmp/tmp.txt ')
Try
For line in F.readlines ():
Print (line)
Finally
F.close ()


Note that we do not have to deal with file open failed IOError, the above wording can work properly, but for each open file, we have to manually close the file handle. If you want to use with to accomplish these functions, you need a proxy class:
Copy CodeThe code is as follows:


Class opened (object):

def __init__ (self, name):
Self.handle = open (name)

def __enter__ (self):
Return Self.handle

def __exit__ (self, type, value, Trackback):
Self.handle.close ()

With opened ('/tmp/a.txt ') as F:
For line in F.readlines ():
Print (line)


Note that we have a name called opened Auxiliary class, and implemented the __enter__ and __exit__ methods, __enter__ method has no parameters, the __exit__ method of 3 parameters, respectively, represents the type of exception, value, and stack information, if there is no exception, The value of 3 entry parameters is none.

If you don't like the definition of class, you can also use the contextlib provided by the Python standard library to implement:
Copy the Code code as follows:


From Contextlib import ContextManager

@contextmanager
Def opened (name):
f = Open (name)
Try
Yield F
Finally
F.close ()

With opened ('/tmp/a.txt ') as F:
For line in F.readlines ():
Print (line)


With the ContextManager function, yield can only return one parameter, and yield is followed by code that handles cleanup work. In our example of reading a file, we close the file handle. Here the principle is the same as the class opened we implemented before, and interested can refer to the source code of ContextManager.

Third, the application scenario

Nonsense so much, so in the end those scenes should use with, there are some excellent examples? Of course, otherwise what is the meaning of this article? The following excerpt from PEP 343.

A template that ensures that the code is unlocked before it executes and releases the lock after execution:
Copy the Code code as follows:


@contextmanager
def locked (lock):
Lock.acquire ()
Try
Yield
Finally
Lock.release ()

With locked (myLock):
# Code here executes with MyLock held. The lock is
# guaranteed to being released when the block was left (even
# if Via return or by an uncaught exception).


Commit and rollback of database transactions:
Copy CodeThe code is as follows:


@contextmanager
def transaction (DB):
Db.begin ()
Try
Yield None
Except
Db.rollback ()
Raise
Else
Db.commit ()


REDIRECT stdout:
Copy CodeThe code is as follows:


@contextmanager
def stdout_redirected (new_stdout):
Save_stdout = Sys.stdout
Sys.stdout = New_stdout
Try
Yield None
Finally
Sys.stdout = Save_stdout

With opened (filename, "w") as F:
With stdout_redirected (f):
print "Hello World"


Note that the above example is not thread-safe and should be used with caution in a multi-threaded environment.


Iv. Summary

With is a simplification of the try...expect...finally syntax and provides a very good way to handle exceptions. There are 2 ways to implement the WITH syntax in Python: class-based and decorator-based,2 are equivalent in principle and can be selected according to the specific scenario.

With originally originated from a kind of block...as ... syntax, but this syntax has been spurned by many, and was finally born with, and it is still possible to refer to PEP-343 and PEP-340 for this period of history.

  • 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.