The biggest reason to keep the try/except/finally blocks in the code itself is that error recovery is usually an integral part of the function.
For example, if we had our own int()
function:
def MyInt(text):
return int(text)
What should we do if text
cannot be converted? Return 0
? Return None
?
If you have many simple cases then I can see a simple decorator being useful, but I think the recipe you linked to tries to do too much: it allows a different function to be activated for each possible exception--in cases such as those (several different exceptions, several different code paths) I would recommend a dedicated wrapper function.
Here's my take on a simple decorator approach:
class ConvertExceptions(object):
func = None
def __init__(self, exceptions, replacement=None):
self.exceptions = exceptions
self.replacement = replacement
def __call__(self, *args, **kwargs):
if self.func is None:
self.func = args[0]
return self
try:
return self.func(*args, **kwargs)
except self.exceptions:
return self.replacement
and sample usage:
@ConvertExceptions(ValueError, 0)
def my_int(value):
return int(value)
print my_int('34') # prints 34
print my_int('one') # prints 0