Sometimes I find myself in the situation where I want to execute several sequential commands like such:
try:
foo(a, b)
except Exception, e:
baz(e)
tr
If they're simple one-line commands, you can wrap them in lambda
s:
for cmd in [
(lambda: foo (a, b)),
(lambda: bar (c, d)),
]:
try:
cmd ()
except StandardError, e:
baz (e)
You could wrap that whole thing up in a function, so it looked like this:
ignore_errors (baz, [
(lambda: foo (a, b)),
(lambda: bar (c, d)),
])
The best approach I have found, is to define a function like such:
def handle_exception(function, reaction, *args, **kwargs):
try:
result = function(*args, **kwargs)
except Exception, e:
result = reaction(e)
return result
But that just doesn't feel or look right in practice:
handle_exception(foo, baz, a, b)
handle_exception(bar, baz, c, d)
In your specific case, you can do this:
try:
foo(a, b)
bar(c, d)
except Exception, e:
baz(e)
Or, you can catch the exception one step above:
try:
foo_bar() # This function can throw at several places
except Exception, e:
baz(e)
You could use the with statement if you have python 2.5 or above:
from __future__ import with_statement
import contextlib
@contextlib.contextmanager
def handler():
try:
yield
except Exception, e:
baz(e)
Your example now becomes:
with handler():
foo(a, b)
with handler():
bar(c, d)
If this is always, always the behaviour you want when a particular function raises an exception, you could use a decorator:
def handle_exception(handler):
def decorate(func):
def call_function(*args, **kwargs):
try:
func(*args, **kwargs)
except Exception, e:
handler(e)
return call_function
return decorate
def baz(e):
print(e)
@handle_exception(baz)
def foo(a, b):
return a + b
@handle_exception(baz)
def bar(c, d):
return c.index(d)
Usage:
>>> foo(1, '2')
unsupported operand type(s) for +: 'int' and 'str'
>>> bar('steve', 'cheese')
substring not found
You could try something like this. This is vaguely C macro-like.
class TryOrBaz( object ):
def __init__( self, that ):
self.that= that
def __call__( self, *args ):
try:
return self.that( *args )
except Exception, e:
baz( e )
TryOrBaz( foo )( a, b )
TryOrBaz( bar )( c, d )