9.9 finally Clause

Operating systems typically can prevent more than one program from manipulating a file at once. When a program finishes processing a file, the program should close it to release the resource. This enables other programs to use the file (if they’re allowed to access it). Closing the file helps prevent a resource leak in which the file resource is not available to other programs because a program using the file never closes it.

The finally Clause of the try Statement

A try statement may have a finally clause as its last clause after any except clauses or else clause. The finally clause is guaranteed to execute, regardless of whether its try suite executes successfully or an exception occurs.8 In other languages that have finally, this makes the finally suite an ideal location to place resource-deallocation code for resources acquired in the corresponding try suite. In Python, we prefer the with statement for this purpose and place other kinds of “clean up” code in the finally suite.

Example

The following IPython session demonstrates that the finally clause always executes, regardless of whether an exception occurs in the corresponding try suite. First, let’s consider a try statement in which no exceptions occur in the try suite:

In [1]: try:
   ...:     print('try suite with no exceptions raised')
   ...: except:
   ...:     print('this will not execute')
   ...: else:
   ...:     print('else executes because no exceptions in the try suite')
   ...: finally:
   ...:     print('finally always executes')
   ...:
try suite with no exceptions raised
else executes because no exceptions in the try suite
finally always executes

In [2]:

The preceding try suite displays a message but does not raise any exceptions. When program control successfully reaches the end of the try suite, the except clause is skipped, the else clause executes and the finally clause displays a message showing that it always executes. When the finally clause terminates, program control continues with the next statement after the try statement. In an IPython session, the next In [] prompt appears.

Now let’s consider a try statement in which an exception occurs in the try suite:

In [2]: try:
   ...:     print('try suite that raises an exception')
   ...:     int('hello')
   ...:     print('this will not execute')
   ...: except ValueError:
   ...:     print('a ValueError occurred')
   ...: else:
   ...:     print('else will not execute because an exception occurred')
   ...: finally:
   ...:     print('finally always executes')
   ...:
try suite that raises an exception
a ValueError occurred
finally always executes

In [3]:

This try suite begins by displaying a message. The second statement attempts to convert the string 'hello' to an integer, which causes the int function to raise a ValueError. The try suite immediately terminates, skipping its last print statement. The except clause catches the ValueError exception and displays a message. The else clause does not execute because an exception occurred. Then, the finally clause displays a message showing that it always executes. When the finally clause terminates, program control continues with the next statement after the try statement. In an IPython session, the next In [] prompt appears.

Combining with Statements and tryexcept Statements

Most resources that require explicit release, such as files, network connections and database connections, have potential exceptions associated with processing those resources. For example, a program that processes a file might raise IOErrors. For this reason, robust file-processing code normally appears in a try suite containing a with statement to guarantee that the resource gets released. The code is in a try suite, so you can catch in except handlers any exceptions that occur and you do not need a finally clause because the with statement handles resource deallocation.

To demonstrate this, first let’s assume you’re asking the user to supply the name of a file and they provide that name incorrectly, such as gradez.txt rather than the file we created earlier grades.txt. In this case, the open call raises a FileNotFoundError by attempting to open a non-existent file:

In [3]: open('gradez.txt')
-------------------------------------------------------------------------
FileNotFoundError                       Traceback (most recent call last)
<ipython-input-3-b7f41b2d5969> in <module>()
----> 1 open('gradez.txt')

FileNotFoundError: [Errno 2] No such file or directory: 'gradez.txt'

To catch exceptions like FileNotFoundError that occur when you try to open a file for reading, wrap the with statement in a try suite, as in:

In [4]: try:
   ...:    with open('gradez.txt', 'r') as accounts:
   ...:        print(f'{"ID":<3}{"Name":<7}{"Grade"}')
   ...:        for record in accounts:
   ...:            student_id, name, grade = record.split()
   ...:            print(f'{student_id:<3}{name:<7}{grade}')
   ...: except FileNotFoundError:
   ...:    print('The file name you specified does not exist')
   ...:
The file name you specified does not exist

tick mark Self Check

  1. (True/False) If a finally clause appears in a function, that finally clause is guaranteed to execute when the function executes, regardless of whether the function raises an exception.
    Answer: False. The finally clause will execute only if program control enters the corresponding try suite.

  2. (Fill-In) Closing a file helps prevent a(n)       in which the file resource is not available to other programs because a program using the file never closes it.
    Answer: resource leak.

  3. (IPython Session) Before executing the IPython session, determine what the following function displays if you call it with the value 10.7, then the value 'Python'?

    def try_it(value)
        try:
           x = int(value)
        except ValueError:
           print(f'{value} could not be converted to an integer')
        else:
           print(f'int({value}) is {int(value)}')
        finally:
           print('finally executed')

    Answer:

    In [1]: def try_it(value):
       ...:     try:
       ...:        x = int(value)
       ...:     except ValueError:
       ...:        print(f'{value} could not be converted to an integer')
       ...:     else:
       ...:        print(f'int({value}) is {int(value)}')
       ...:     finally:
       ...:        print('finally executed')
       ...:
    
    In [2]: try_it(10.7)
    int(10.7) is 10
    finally executed
    
    In [3]: try_it('Python')
    Python could not be converted to an integer
    finally executed
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.147.87