decorator exception outsourcing

Many try / except / finally-clauses not only โ€œguessโ€ my code, but I often find myself using the same exception handling for similar tasks. Therefore, I considered the possibility of reducing redundancy by "outsourcing" them to ... a decorator.

Since I was sure that I would not be the first to come to this conclusion, I found googled and found this - imho - an ingenious recipe that added the ability to handle more than one exception.

But I was surprised why this does not seem to be a widely known and used practice as such, so I was wondering if there was any aspect that I did not consider?

  • Is it fake to use a decorator pattern to handle exceptions, or am I just missing it all the time? Please enlighten me! What are the pitfalls?

  • Perhaps there is even a package / module that supports the creation of such exception handling in a reasonable way?

+33
python decorator exception-handling
Mar 10 2018-12-12T00:
source share
3 answers

The biggest reason for storing try / except / finally blocks in the code itself is that error recovery is usually an integral part of the function.

For example, if we have our int() function:

 def MyInt(text): return int(text) 

What if text cannot be converted? Return 0 ? Return None ?

If you have a lot of simple cases, I see that a simple decorator is useful, but I think that the recipe you linked tries to do too much: it allows you to activate another function for every possible exception - in cases like those (several different exceptions , several different codes), I would recommend a dedicated wrapper function.

Here is my approach to a simple decorator:

 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 use:

 @ConvertExceptions(ValueError, 0) def my_int(value): return int(value) print my_int('34') # prints 34 print my_int('one') # prints 0 
+20
Mar 10 2018-12-12T00:
source share

Basically, the drawback is that you no longer decide how to handle the exception in the calling context (just allowing the exception to be thrown). In some cases, this may result in a lack of separation of responsibilities.

+4
Mar 10 2018-12-12T00:
source share
  • A decorator in Python is not the same as a Decorator pattern, if there is some similarity. Itโ€™s not entirely clear what you mean here, but I think you mean one of Python (so itโ€™s better not to use a word pattern)

  • Python decorators are not so useful for handling exceptions, because you will need to pass some context to the decorator. That is, you either go through the global context or hide the definitions of functions in some external context, which requires, I would say, a LISP -like way of thinking.

  • Instead of decorators, you can use context managers. And I use them for this purpose.

-one
Mar 10 '12 at 15:00
source share



All Articles