try-except-else-finally in Python

Description

Errors detected during execution are called exceptions and are not unconditionally fatal.

Official tutorial

Errors and Exceptions Chapter in python official website.

Self-Summary for Exceptions

Exception

Here is an exception example.

>>> 10 * (1/0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero

Handling Exceptions

We can use try statement to handle exceptions.

Basic usage of try statement: try-except statement

Basic usage of try statement is try-except pair.

The code body which may occur exceptions is put into try body, and handling exceptions code is put into except body. For example:

try:
    t= 3 / 0
except ZeroDivisionError:
    print "Oops! Zeros Division Error happens."
except ZeroDivisionError: 
    print "Oops! Zeros Division Error happens."

The try statement works as follows.

  • First, the try clause (the statement(s) between the try and except keywords) is executed.
  • If no exception occurs, the except clause is skipped and execution of the trystatement is finished.
  • If an exception occurs during execution of the try clause, the rest of the clause is skipped. Then if its type matches the exception named after the except keyword, the except clause is executed, and then execution continues after the trystatement.
  • If an exception occurs which does not match the exception named in the except clause, it is passed on to outer try statements; if no handler is found, it is an unhandled exception and execution stops with a message as shown above. (That means the program will stop rather than continue. In another word, the rest of the clause can not be executed, because unhandled exception occurs.)

Note: the except body can not be empty, something must be put here. If you have not decided what to code, just put pass statement here.

try-except-else statement

The try-except statement has an optional else clause, which, when present, must follow all except clauses. It is useful for code that must be executed if the try clause does not raise an exception. That means, else clause will not be excuted if an exception occurs in try clause. For example:

try:
    t= 3 / 0
except ValueError:
    print "Oops! That was no valid number."
except ZeroDivisionError:
    print "Oops! Zeros Division Error happens."
else:
    print "Else clause."

The output is: Oops! Zeros Division Error happens. , but Else clause. will not be printed.

If t = 3 / 1, then the output will be

Oops! Zeros Division Error happens.
Else clause.

try-except-else-finally statement

finally clause will be excuted whatever happens in try clause, it must be excuted.  And finally clause is called Clean-up Actions in Python. For example:

try:
    t= 3 / 0
except ValueError:
    print "Oops! That was no valid number."
except ZeroDivisionError:
    print "Oops! Zeros Division Error happens."
else:
    print "Else clause."
finally:
    print "Execution finished."

Even though ZeroDivisionError occurs in try clause, Execution finished. will be printed.

raise clause

Exception can be raised by raise clause. Rest of code will not be excuted if exception raised by raise clause is not handled. For example:

try:
    t= 3 / 0
except ValueError:
    print "Oops! That was no valid number."
except ZeroDivisionError:
    print "Oops! Zeros Division Error happens."
    raise NameError('Hi, here is a NameError!')
else:
    print "Else clause."
finally:
    print "Execution finished."

Output:

Oops! Zeros Division Error happens.
Traceback (most recent call last):
  File "test2.py", line 8, in <module>
    raise NameError('Hi, here is a NameError!')
NameError: Hi, here is a NameError!

Program exit because there is unhandled exception, and finially clause is not excuted because Execution finished. is not printed.

If we change the code a little bit, for example:

try:
    t= 3 / 0
except ValueError:
    print "Oops! That was no valid number."
except ZeroDivisionError:
    print "Oops! Zeros Division Error happens."
    try:
        raise NameError('Hi, here is a NameError!')
    except NameError:
        print 'NameError is handled.'        
else:
    print "Else clause."
finally:
    print "Execution finished."

Output:

Oops! Zeros Division Error happens.
NameError is handled.
Execution finished.

As you can see, finally clause is excuted because NameError is handled in the above code.

Predefined Clean-up Actions

This paragraph is cited from official tutorial document.

Some objects define standard clean-up actions to be undertaken when the object is no longer needed, regardless of whether or not the operation using the object succeeded or failed. Look at the following example, which tries to open a file and print its contents to the screen.

for line in open("myfile.txt"):
    print line,

The problem with this code is that it leaves the file open for an indeterminate amount of time after the code has finished executing. This is not an issue in simple scripts, but can be a problem for larger applications. The with statement allows objects like files to be used in a way that ensures they are always cleaned up promptly and correctly.

with open("myfile.txt") as f:
    for line in f:
        print line,

After the statement is executed, the file f is always closed, even if a problem was encountered while processing the lines. Other objects which provide predefined clean-up actions will indicate this in their documentation.

发表评论

电子邮件地址不会被公开。 必填项已用*标注

19 − 2 =

68 + = 69