“outsourcing” exception-handling to a decorator [closed]

妖精的绣舞 提交于 2019-12-02 19:54:14
Ethan Furman

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

Basically, the drawback is that you no longer get to decide how to handle the exception in the calling context (by just letting the exception propagate). In some cases this may result in a lack of separation of responsibility.

  1. Decorator in Python is not the same as the Decorator pattern, thought there is some similarity. It is not completely clear waht you mean here, but I think you mean the one from Python (thus, it is better not to use the word pattern)

  2. Decorators from Python are not that useful for exception handling, because you would need to pass some context to the decorator. That is, you would either pass a global context, or hide function definitions within some outer context, which requires, I would say, LISP-like way of thinking.

  3. Instead of decorators you can use contextmanagers. And I do use them for that purpose.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!