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)