许多try / except / finally-clause不仅“uglify”我的代码,而且我发现自己经常对类似的任务使用相同的异常处理。因此,我正在考虑通过将它们“外包”给装饰者来减少冗余。
因为我肯定不是第一个得出这个结论的人,所以我用Google搜索并发现了这个 - imho - 巧妙recipe,它增加了处理多个例外的可能性。
但令我感到惊讶的是,为什么这似乎不是一个广为人知的习惯本身,所以我想知道是否有一个方面我没有考虑?
使用装饰器模式进行异常处理是假的还是我一直都想念它?请赐教!有什么陷阱?
是否有一个包/模块支持以合理的方式创建此类异常处理?
答案 0 :(得分:25)
在代码本身中保留try / except / finally块的最大原因是错误恢复通常是函数的一个组成部分。
例如,如果我们有自己的int()
函数:
def MyInt(text):
return int(text)
如果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
和样本用法:
@ConvertExceptions(ValueError, 0)
def my_int(value):
return int(value)
print my_int('34') # prints 34
print my_int('one') # prints 0
答案 1 :(得分:5)
基本上,缺点是你不再决定如何在调用上下文中处理异常(只是让异常传播)。在某些情况下,这可能导致责任分离不足。
答案 2 :(得分:-1)
Python中的装饰器与装饰器模式不同,认为有一些相似之处。你在这里的意思并不完全清楚,但我认为你的意思是Python中的那个(因此,最好不要使用模式这个词)
Python中的装饰器对异常处理没有用,因为你需要将一些上下文传递给装饰器。也就是说,你要么传递一个全局上下文,要么在某些外部上下文中隐藏函数定义,这就要求我说LISP式的思维方式。
您可以使用上下文管理器代替装饰器。我确实将它们用于此目的。