General decorator to wrap try except in python? General decorator to wrap try except in python? python python

General decorator to wrap try except in python?


You could use a defaultdict and the context manager approach as outlined in Raymond Hettinger's PyCon 2013 presentation

from collections import defaultdictfrom contextlib import contextmanager@contextmanagerdef ignored(*exceptions):  try:    yield  except exceptions:    pass item = defaultdict(str)obj = dict()with ignored(Exception):  item['a'] = obj.get(2).get(3) print item['a']obj[2] = dict()obj[2][3] = 4with ignored(Exception):  item['a'] = obj.get(2).get(3) print item['a']


There are lots of good answers here, but I didn't see any that address the question of whether you can accomplish this via decorators.

The short answer is "no," at least not without structural changes to your code. Decorators operate at the function level, not on individual statements. Therefore, in order to use decorators, you would need to move each of the statements to be decorated into its own function.

But note that you can't just put the assignment itself inside the decorated function. You need to return the rhs expression (the value to be assigned) from the decorated function, then do the assignment outside.

To put this in terms of your example code, one might write code with the following pattern:

@return_on_failure('')def computeA():    item['a'] = myobject.get('key').METHOD_THAT_DOESNT_EXIST()item["a"] = computeA()

return_on_failure could be something like:

def return_on_failure(value):  def decorate(f):    def applicator(*args, **kwargs):      try:         return f(*args,**kwargs)      except:         print('Error')         return value    return applicator  return decorate


It's very easy to achieve using configurable decorator.

def get_decorator(errors=(Exception, ), default_value=''):    def decorator(func):        def new_func(*args, **kwargs):            try:                return func(*args, **kwargs)            except errors, e:                print "Got error! ", repr(e)                return default_value        return new_func    return decoratorf = get_decorator((KeyError, NameError), default_value='default')a = {}@fdef example1(a):    return a['b']@fdef example2(a):    return doesnt_exist()print example1(a)print example2(a)

Just pass to get_decorator tuples with error types which you want to silence and default value to return.Output will be

Got error!  KeyError('b',)defaultGot error!  NameError("global name 'doesnt_exist' is not defined",)default

Edit: Thanks to martineau i changed default value of errors to tuples with basic Exception to prevents errors.