A Brief Introduction to the try and finally and with methods in Python, pythonfinally

Source: Internet
Author: User

A Brief Introduction to the try and finally and with methods in Python, pythonfinally

Using Python to do a very common thing: open the file, read the file row by row, and finally turn off the file; further demand is that this may be an optional function in the program, if there is any problem, such as the file cannot be opened, or the reading error occurs, capture all exceptions in the function, output a line of warning and exit. the Code may look like this at the beginning
 

def read_file():   try:     f = open('yui', 'r')     print ''.join(f.readlines())   except:     print 'error occurs while reading file'  finally:     f.close()

However, this obviously cannot work because f is defined in the try block and cannot be referenced in finally.

If f is extracted to the external part of the try block, such
 

def read_file():    f = open('azusa', 'r')   try:     print ''.join(f.readlines())   except:     print 'error occurs while reading file'  finally:     f.close()

The problem is that when the file fails to be opened, an exception will not be caught.

The way to be frustrated is, set another try.
 

def read_file():    try:     f = open('sawako', 'r')     try:       print ''.join(f.readlines())     except:       print 'error occurs while reading file'    finally:       f.close()    except:      print 'error occurs while reading file'

Of course, this is not just a matter of more indentation, but even the warning output is too white.

The formal method is to use the with structure introduced by Python, for example
 

def readFile():   try:      with open('mio', 'r') as f:       print ''.join(f.readlines())   except:     print 'error occurs while reading file'

When the file fails to be opened, the exception will naturally be aborted; otherwise, the opened file will be automatically closed after the with block ends.

Apart from opening files, is there anything else that can be used for? Or, how can we customize something so that it can be used?
Directly answer the next question. The secret is that when the Python Virtual Machine exits from the with block, it will find the _ exit _ method of the object and call it, put the action to release resources in the _ exit _ function. In addition, an _ enter _ function is required for the object. when entering the with block, this function is called, and its return value will be the value referenced after. A simple example is:
 

class Test:   def __init__(self):     print 'init'   def __enter__(self):     print 'enter'    return self   def __exit__(self, except_type, except_obj, tb):     print except_type     print except_obj     import traceback     print ''.join(traceback.format_tb(tb))     print 'exit'    return True with Test() as t:   raise ValueError('kon!')

Run this code and the output will be
 

init enter <type 'exceptions.ValueError'> kon!  File "test.py", line 17, in <module>   raise ValueError('kon!')  exit

The _ exit _ function accepts three parameters: exception object type, exception object, and call stack. if the with block Exits normally, all these parameters will be None. returns True, indicating that the exception has been processed and will not be thrown out.

For more information, see PEP 343 (This number is really good, 7 3 ).

The following describes the instance usage and advanced usage of the with statement:

Python high-end, atmospheric, and advanced with statements

Before talking about the with statement, let's take a look at a simple piece of code.
 

lock = threading.Lock()...lock.acquire()elem = heapq.heappop(heap)lock.release()

It is simple and intuitive. When multiple threads share a priority queue, first use the mutex lock. acquire () locks the priority queue, then retrieves elements, and then locks. release the lock.

Although a seemingly logical process, there is a huge bug hidden in it: when there are no elements in the heap, an IndexError exception will be thrown and the stack will be rolled back, then lock. release () will not be executed at all, and the lock will never be released, so a deadlock is a favorite problem. This is why many gods hate exceptions. The classic Java-style solution is
 

lock = threading.Lock()...lock.acquire()try:  elem = heapq.heappop(heap)finally:  lock.release()

This is acceptable, but how can we see dirty is very different from the elegant and simple style of Python. In fact, since Python2.5 introduced the with statement, everything has become very simple:
 

lock = threading.Lock()...with lock:  elem = heapq.heappop(heap)

The lock will be released no matter how it leaves the with statement code block.
The with statement is designed to make it easy and clear to clean up resources that need to be solved through try... finally. Its usage is
 

with expression [as variable]:  with-block

Expression returns an object called "context manager", which is assigned to variable (if any ). The context manager object has two methods: _ enter _ () and _ exit _ (). It is obviously called when you enter with-block, it is called when you exit with-block.

Such objects do not need to be implemented by themselves. Many APIs in the Python standard library have already implemented these two methods. The most common example is to read and write open statements of files.
 

with open('1.txt', encoding = 'utf-8') as fp:  lines = fp.readlines()

Whether the with statement block is left normally or due to exceptions, the opened file resources are always released.
Next, we will discuss some practical methods used by the with statement in combination with the contextlib library. For example, you need to open two files at the same time and read one write file at a time. At this time, you can write as follows:
 

from contextlib import nested...with nested(open('in.txt'), open('out.txt', 'w')) as (fp_in, fp_out):  ...

In this way, we can save the nesting of two with statements. What if there are APIs that do not support "context manager" yet? For example, urllib. request. urlopen (), because the returned object is not "context manager", you must call the close method at the end.
Similar to this API, contextlib provides a method called closing, which will automatically call the close method of the object when leaving the with statement. Therefore, urlopen can also be written as follows:
 

from contextlib import closing...with closing(urllib.request.urlopen('http://www.yahoo.com')) as f:  for line in f:    sys.stdout.write(line)

Using Python to do a very common thing: open the file, read the file row by row, and finally turn off the file; further demand is that this may be an optional function in the program, if there is any problem, such as the file cannot be opened, or the reading error occurs, capture all exceptions in the function, output a line of warning and exit. the Code may look like this at the beginning
 

def read_file():   try:     f = open('yui', 'r')     print ''.join(f.readlines())   except:     print 'error occurs while reading file'  finally:     f.close()

However, this obviously cannot work because f is defined in the try block and cannot be referenced in finally.

If f is extracted to the external part of the try block, such
 

def read_file():    f = open('azusa', 'r')   try:     print ''.join(f.readlines())   except:     print 'error occurs while reading file'  finally:     f.close()

The problem is that when the file fails to be opened, an exception will not be caught.

The way to be frustrated is, set another try.
 

def read_file():    try:     f = open('sawako', 'r')     try:       print ''.join(f.readlines())     except:       print 'error occurs while reading file'    finally:       f.close()    except:      print 'error occurs while reading file'

Of course, this is not just a matter of more indentation, but even the warning output is too white.

The formal method is to use the with structure introduced by Python, for example
 

def readFile():   try:      with open('mio', 'r') as f:       print ''.join(f.readlines())   except:     print 'error occurs while reading file'

When the file fails to be opened, the exception will naturally be aborted; otherwise, the opened file will be automatically closed after the with block ends.

Apart from opening files, is there anything else that can be used for? Or, how can we customize something so that it can be used?
Directly answer the next question. The secret is that when the Python Virtual Machine exits from the with block, it will find the _ exit _ method of the object and call it, put the action to release resources in the _ exit _ function. In addition, an _ enter _ function is required for the object. when entering the with block, this function is called, and its return value will be the value referenced after. A simple example is:
 

class Test:   def __init__(self):     print 'init'   def __enter__(self):     print 'enter'    return self   def __exit__(self, except_type, except_obj, tb):     print except_type     print except_obj     import traceback     print ''.join(traceback.format_tb(tb))     print 'exit'    return True with Test() as t:   raise ValueError('kon!')

Run this code and the output will be
 

init enter <type 'exceptions.ValueError'> kon!  File "test.py", line 17, in <module>   raise ValueError('kon!')  exit

The _ exit _ function accepts three parameters: exception object type, exception object, and call stack. if the with block Exits normally, all these parameters will be None. returns True, indicating that the exception has been processed and will not be thrown out.

For more information, see PEP 343 (This number is really good, 7 3 ).

The following describes the instance usage and advanced usage of the with statement:

Python high-end, atmospheric, and advanced with statements

Before talking about the with statement, let's take a look at a simple piece of code.
 

lock = threading.Lock()...lock.acquire()elem = heapq.heappop(heap)lock.release()

It is simple and intuitive. When multiple threads share a priority queue, first use the mutex lock. acquire () locks the priority queue, then retrieves elements, and then locks. release the lock.

Although a seemingly logical process, there is a huge bug hidden in it: when there are no elements in the heap, an IndexError exception will be thrown and the stack will be rolled back, then lock. release () will not be executed at all, and the lock will never be released, so a deadlock is a favorite problem. This is why many gods hate exceptions. The classic Java-style solution is
 

lock = threading.Lock()...lock.acquire()try:  elem = heapq.heappop(heap)finally:  lock.release()

This is acceptable, but how can we see dirty is very different from the elegant and simple style of Python. In fact, since Python2.5 introduced the with statement, everything has become very simple:
 

lock = threading.Lock()...with lock:  elem = heapq.heappop(heap)

The lock will be released no matter how it leaves the with statement code block.
The with statement is designed to make it easy and clear to clean up resources that need to be solved through try... finally. Its usage is
 

with expression [as variable]:  with-block

Expression returns an object called "context manager", which is assigned to variable (if any ). The context manager object has two methods: _ enter _ () and _ exit _ (). It is obviously called when you enter with-block, it is called when you exit with-block.

Such objects do not need to be implemented by themselves. Many APIs in the Python standard library have already implemented these two methods. The most common example is to read and write open statements of files.
 

with open('1.txt', encoding = 'utf-8') as fp:  lines = fp.readlines()

Whether the with statement block is left normally or due to exceptions, the opened file resources are always released.
Next, we will discuss some practical methods used by the with statement in combination with the contextlib library. For example, you need to open two files at the same time and read one write file at a time. At this time, you can write as follows:
 

from contextlib import nested...with nested(open('in.txt'), open('out.txt', 'w')) as (fp_in, fp_out):  ...

In this way, we can save the nesting of two with statements. What if there are APIs that do not support "context manager" yet? For example, urllib. request. urlopen (), because the returned object is not "context manager", you must call the close method at the end.
Similar to this API, contextlib provides a method called closing, which will automatically call the close method of the object when leaving the with statement. Therefore, urlopen can also be written as follows:
 

from contextlib import closing...with closing(urllib.request.urlopen('http://www.yahoo.com')) as f:  for line in f:    sys.stdout.write(line)


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.