Go With...as in Python ...

Source: Internet
Author: User

Let's start with a common problem, file open:

1234567 try :      f = open ( ' xxx ' Code class= "python spaces" >     do something except :       do something finally Code class= "Python plain" >:      f.close ()

In fact, I personally see this on the Internet more than once, this is wrong.
The first is correct as follows:

1234567891011 try:    f = open(‘xxx‘)except:    print ‘fail to open‘    exit(-1)try:    do somethingexcept:    do somethingfinally:    f.close()

It's a lot of trouble, but the right way to do that is to write.
Why do we write finally because it prevents the program from throwing an exception and finally cannot close the file, but the need to close the file is a prerequisite that the file is already open.
In the first error code, if the exception occurs at F=open (' xxx '), such as the file does not exist, it is immediately possible to know that execution of f.close () is meaningless. The corrected solution is the second piece of code.

Okay, I'm going to start talking about the with syntax.

First, we start with the following question, Try-finally's grammatical structure:

12345 setthings uptry:    do somethingfinally:    tear things down

This thing is a common structure, such as file Open, it means set things up f=open(‘xxx‘) tear things down f.close() . In such things as multi-threaded locks, resource requests, eventually there is a need to release. The try...finally structure ensures that the tear things down will always be executed, even if the above do something work is not fully executed.

If this structure is often used, we can first take a more elegant approach to encapsulation!

1234567891011 def controlled_execution(callback):    set things up    try:        callback(thing)    finally:        tear things downdef my_function(thing):    do somethingcontrolled_execution(my_function)

Encapsulation is a good way to support code reuse, but this approach is very dirty, especially if you have to modify some local variables in the Do something (it becomes a function call, which brings trouble to the scope of the variable).

Another option is to use the generator, but only to generate the data once, and we use the for-in structure to call him:

123456789 def controlled_execution():    set things up    try:        yield thing    finally:        tear things down        for thing in controlled_execution():    do something with thing

Because thing has only one, the yield statement needs to be executed only once. Of course, this is simply awful from the point of view of code readability, which is elegant. We still use the for loop when we're sure that the for loop executes only once, and it's hard to understand what the loop here is for someone who doesn't know.

The ultimate solution for the Python-dev team. (Python 2.5 adds syntax for the with expression later)

123456789 class controlled_execution:    def __enter__(self):        set things up        return thing    def __exit__(self, type, value, traceback):        tear things down        with controlled_execution() as thing:        do something

Here, Python uses the syntax of With-as. When Python executes this sentence, it invokes the __ENTER__ function and passes the value of the function return to the variable specified after as. After that, Python executes the block of statements below do something. Finally, no matter what exception occurs in the statement block, the __exit__ is executed when it leaves.
In addition, __exit__ in addition to tear things down, can also be abnormal monitoring and processing, note the following several parameters. To skip an exception, you only need to return the function true. The following sample code skips all TypeError and throws the other exceptions normally.

12 def__exit__(self, type, value, traceback):    returnisinstance(value, TypeError)

After python2.5 and later, the file object has written the __enter__ and __exit__ functions, which we can test:

123456789101112 >>> f = open("x.txt")>>> f<open file ‘x.txt‘, mode ‘r‘ at 0x00AE82F0>>>> f.__enter__()<open file ‘x.txt‘, mode ‘r‘ at 0x00AE82F0>>>> f.read(1)‘X‘>>> f.__exit__(None, None, None)>>> f.read(1)Traceback (most recent call last):    File "<stdin>", line 1, in <module>ValueError: I/O operation on closed file

After that, we only need to do this if we want to open the file and make sure to close it last:

123 with open("x.txt") as f:    data =f.read()    do something with data

If there are multiple items, we can write this:

12 with open("x.txt") as f1, open(‘xxx.txt‘) as f2:    do something with f1,f2

As mentioned above, the __EXIT__ function can handle partial exceptions, and if we do not handle exceptions in this function, he will throw them normally, which is what we can write (Python version 2.7 and above, the previous version reference uses the contextlib.nested library function):

12345 try:    with open( "a.txt") as f :        do somethingexceptxxxError:    do something about exception

In summary, the WITH-AS expression greatly simplifies the work of the Finally, which is very helpful for maintaining the elegance of the code.

Go With...as in Python ...

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.