"外包"异常处理给装饰者

Don*_*ion 43 python exception-handling decorator python-2.6

许多try/except/finally-clause不仅"uglify"我的代码,而且我发现自己经常对类似的任务使用相同的异常处理.所以我正在考虑通过将它们"外包"给一个装饰来减少冗余.

因为我肯定不是第一个得出这个结论的人,所以我用Google搜索并发现了这个 - imho - 巧妙的配方,增加了处理多个例外的可能性.

但我很惊讶为什么这似乎不是一个广为人知的习惯本身,所以我想知道是否有一个方面我没有考虑?

  1. 使用装饰器模式进行异常处理是假的还是我一直都想念它?请赐教!有什么陷阱?

  2. 甚至可能有一个包/模块支持以合理的方式创建这样的异常处理?

Eth*_*man 25

在代码本身中保留try/except/finally块的最大原因是错误恢复通常是函数的组成部分.

例如,如果我们有自己的int()功能:

def MyInt(text):
    return int(text)
Run Code Online (Sandbox Code Playgroud)

如果text无法转换,我们该怎么办?回来0?回来None

如果你有很多简单的案例,那么我可以看到一个简单的装饰器是有用的,但我认为你链接的配方试图做太多:它允许为每个可能的异常激活不同的功能 - 在这种情况下(如果几个不同的例外,几个不同的代码路径)我会推荐一个专用的包装函数.

这是我对简单装饰器方法的看法:

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
Run Code Online (Sandbox Code Playgroud)

和样品用法:

@ConvertExceptions(ValueError, 0)
def my_int(value):
    return int(value)

print my_int('34')      # prints 34
print my_int('one')     # prints 0
Run Code Online (Sandbox Code Playgroud)


Kar*_*tel 5

基本上,缺点是您不再需要决定如何在调用上下文中处理异常(仅通过传播异常)即可。在某些情况下,这可能导致缺乏责任分离。