Python Exceptions
Exception handling in Python
Tim Muller & Rik van Achterberg | 07-08-2013
Coding styles: LBYL vs EAFP
● Look Before You Leap
○ “[...] explicitly tests for pre-conditions before making calls or
lookups. This style contrasts with the EAFP approach and is
characterized by the presence of many if statements.”
● Easier to Ask for Forgiveness than Permission
○ “[...] assumes the existence of valid keys or attributes and catches
exceptions if the assumption proves false. This clean and fast style
is characterized by the presence of many try and except
statements. The technique contrasts with the LBYL style common
to many other languages such as C.”
When to use
“All errors are exceptions, but not all exceptions are errors”
Use exception handling to gracefully recover from application errors.
But: It’s perfectly allowed, and sometimes necessary, to utilize
exception handling for general application control flow.
(EOFError, for example)
We all know this
try:
execute_some_code()
except:
handle_gracefully()
try:
execute_some_code()
except:
handle_gracefully()
We all know this
● Main action:
○ Code to be executed that potentially might cause exception(s)
● Exception handler:
○ Code that recovers from an exception
Exception handler
Main action
But don’t do it.
Catching too broad exceptions is potentially dangerous.
Among others, this “wildcard” handler will catch:
● system exit triggers
● memory errors
● typos
● anything else you might not have considered
try:
execute_some_code()
except:
handle_gracefully()
Better:
Catching specific exceptions
try:
execute_some_code()
except SomeException:
handle_gracefully()
Catching multiple exceptions
Handling them all the same way
try:
execute_some_code()
except (SomeException, AnotherException):
handle_gracefully()
Catching multiple exceptions
Handling them separately
try:
execute_some_code()
except SomeException:
handle_gracefully()
except AnotherException:
do_another_thing()
Raising exceptions
Exceptions can be raised using raise <exception>
with optional arguments.
raise RuntimeError
raise RuntimeError ()
raise RuntimeError ("error message" )
raise RuntimeError , "error message"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: error message
Accessing the exception
Use “as” to access the exception object
(using a comma is deprecated)
try:
raise RuntimeError ("o hai")
except RuntimeError as e:
print e.message
>>> o hai
Propagating exceptions
Try-blocks can be nested;
All exceptions propagate to the top-level “root exception handler” if
uncaught.
The (default) root exception handler terminates
the Python process.
try:
try:
raise SomeException
except SomeException:
print "Inner"
except SomeException:
print "Outer"
>>> Inner
Propagating exceptions
Try-blocks can be nested;
All exceptions propagate to the top-level “root exception handler” if
uncaught.
try:
try:
raise SomeException
except AnotherException:
print "Inner"
except SomeException:
print "Outer"
>>> Outer
Propagating exceptions
Propagation can be forced by using raise without arguments.
this re-raises the most recent exception
This is useful for e.g. exception logging .
try:
try:
raise SomeException
except SomeException:
print "Propagating"
raise
except SomeException:
print "Outer"
>>> Propagating
>>> Outer
More cool stuff
Code in the finally block will always be executed*
Write termination actions here.
* Unless Python crashes completely
try:
open_file()
except IOError:
print "Exception caught"
finally:
close_file()
More cool stuff
Code in the finally block will always be executed
it’s not even necessary to specify a handler.
This code will propagate any exception.
try:
open_file()
finally:
close_file()
More cool stuff
Code in the else block will be executed when no exception is raised
try:
open_file()
except IOError:
print "Exception caught"
else:
print "Everything went according to plan"
finally:
close_file()
Exception matching
Exceptions are matched by superclass relationships.
try:
raise RuntimeError
except Exception as e:
print e.__class__
# <type 'exceptions.RuntimeError'>
BaseException
Exception
StandardError
RuntimeError
Exception matching
Exceptions are matched by superclass relationships.
This way, exception hierarchies can be designed.
For example, OverflowError, ZeroDivisionError and FloatingPointError
are all subclasses of ArithmeticError.
Just write a handler for ArithmeticError to catch any of them.
Writing your own
It’s as simple as
class MyException (MyBaseException):
pass
raise HandException(question)
try:
raise HandException( "I have a question" )
except HandException:
question = raw_input()
answer = generate_answer(question)
raise AnswerException(answer)
finally:
talks.next()

Python exceptions

  • 1.
    Python Exceptions Exception handlingin Python Tim Muller & Rik van Achterberg | 07-08-2013
  • 2.
    Coding styles: LBYLvs EAFP ● Look Before You Leap ○ “[...] explicitly tests for pre-conditions before making calls or lookups. This style contrasts with the EAFP approach and is characterized by the presence of many if statements.” ● Easier to Ask for Forgiveness than Permission ○ “[...] assumes the existence of valid keys or attributes and catches exceptions if the assumption proves false. This clean and fast style is characterized by the presence of many try and except statements. The technique contrasts with the LBYL style common to many other languages such as C.”
  • 3.
    When to use “Allerrors are exceptions, but not all exceptions are errors” Use exception handling to gracefully recover from application errors. But: It’s perfectly allowed, and sometimes necessary, to utilize exception handling for general application control flow. (EOFError, for example)
  • 4.
    We all knowthis try: execute_some_code() except: handle_gracefully()
  • 5.
    try: execute_some_code() except: handle_gracefully() We all knowthis ● Main action: ○ Code to be executed that potentially might cause exception(s) ● Exception handler: ○ Code that recovers from an exception Exception handler Main action
  • 6.
    But don’t doit. Catching too broad exceptions is potentially dangerous. Among others, this “wildcard” handler will catch: ● system exit triggers ● memory errors ● typos ● anything else you might not have considered try: execute_some_code() except: handle_gracefully()
  • 7.
  • 8.
    Catching multiple exceptions Handlingthem all the same way try: execute_some_code() except (SomeException, AnotherException): handle_gracefully()
  • 9.
    Catching multiple exceptions Handlingthem separately try: execute_some_code() except SomeException: handle_gracefully() except AnotherException: do_another_thing()
  • 10.
    Raising exceptions Exceptions canbe raised using raise <exception> with optional arguments. raise RuntimeError raise RuntimeError () raise RuntimeError ("error message" ) raise RuntimeError , "error message" Traceback (most recent call last): File "<stdin>", line 1, in <module> RuntimeError: error message
  • 11.
    Accessing the exception Use“as” to access the exception object (using a comma is deprecated) try: raise RuntimeError ("o hai") except RuntimeError as e: print e.message >>> o hai
  • 12.
    Propagating exceptions Try-blocks canbe nested; All exceptions propagate to the top-level “root exception handler” if uncaught. The (default) root exception handler terminates the Python process. try: try: raise SomeException except SomeException: print "Inner" except SomeException: print "Outer" >>> Inner
  • 13.
    Propagating exceptions Try-blocks canbe nested; All exceptions propagate to the top-level “root exception handler” if uncaught. try: try: raise SomeException except AnotherException: print "Inner" except SomeException: print "Outer" >>> Outer
  • 14.
    Propagating exceptions Propagation canbe forced by using raise without arguments. this re-raises the most recent exception This is useful for e.g. exception logging . try: try: raise SomeException except SomeException: print "Propagating" raise except SomeException: print "Outer" >>> Propagating >>> Outer
  • 15.
    More cool stuff Codein the finally block will always be executed* Write termination actions here. * Unless Python crashes completely try: open_file() except IOError: print "Exception caught" finally: close_file()
  • 16.
    More cool stuff Codein the finally block will always be executed it’s not even necessary to specify a handler. This code will propagate any exception. try: open_file() finally: close_file()
  • 17.
    More cool stuff Codein the else block will be executed when no exception is raised try: open_file() except IOError: print "Exception caught" else: print "Everything went according to plan" finally: close_file()
  • 18.
    Exception matching Exceptions arematched by superclass relationships. try: raise RuntimeError except Exception as e: print e.__class__ # <type 'exceptions.RuntimeError'> BaseException Exception StandardError RuntimeError
  • 19.
    Exception matching Exceptions arematched by superclass relationships. This way, exception hierarchies can be designed. For example, OverflowError, ZeroDivisionError and FloatingPointError are all subclasses of ArithmeticError. Just write a handler for ArithmeticError to catch any of them.
  • 20.
    Writing your own It’sas simple as class MyException (MyBaseException): pass
  • 21.
    raise HandException(question) try: raise HandException("I have a question" ) except HandException: question = raw_input() answer = generate_answer(question) raise AnswerException(answer) finally: talks.next()