我正在用Python编写一个程序,我的类中的几乎所有方法都是这样编写的:
def someMethod(self):
try:
#...
except someException:
#in case of exception, do something here
#e.g display a dialog box to inform the user
#that he has done something wrong
随着类的增长,一遍又一遍地编写相同的try-except块有点烦人。是否有可能为全班创造某种“全球”例外? Python中推荐的处理方法是什么?
答案 0 :(得分:9)
编写一个或多个异常处理函数,在给定函数和其中引发的异常的情况下,执行您想要执行的操作(例如,显示警报)。如果您需要多个,请写下来。
def message(func, e):
print "Exception", type(e).__name__, "in", func.__name__
print str(e)
现在编写一个装饰器,将给定的处理程序应用于被调用的函数:
import functools
def handle_with(handler, *exceptions):
try:
handler, cleanup = handler
except TypeError:
cleanup = lambda f, e: None
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except exceptions or Exception as e:
return handler(func, e)
finally:
cleanup(func, e)
return wrapper
return decorator
这仅捕获您指定的例外。如果您未指定任何内容,则会捕获Exception
。另外,第一个参数可以是两个处理函数的元组(或其他序列);第二个处理程序(如果给定)在finally
子句中调用。从主处理程序返回的值将作为函数调用的值返回。
现在,鉴于上述情况,您可以写下:
@handle_with(message, TypeError, ValueError)
def add(x, y):
return x + y
您也可以使用上下文管理器执行此操作:
from contextlib import contextmanager
@contextmanager
def handler(handler, *exceptions):
try:
handler, cleanup = handler
except TypeError:
cleanup = lambda e: None
try:
yield
except exceptions or Exception as e:
handler(e)
finally:
cleanup(e)
现在你可以写:
def message(e):
print "Exception", type(e).__name__
print str(e)
def add(x, y):
with handler(message, TypeError, ValueError):
return x + y
请注意,上下文管理器不知道它在哪个函数中(您可以使用inspect
找到它,sorta,虽然这是“魔术”,所以我没有这样做)所以它给了你一些不太有用的信息。此外,上下文管理器不会让您有机会在处理程序中返回任何内容。
答案 1 :(得分:3)
我可以想到两个选择:
try
块中每个方法的装饰器。try
块中调用适当的方法,然后调用该方法而不是单个方法。也就是说,不是调用obj.someMethod()
,obj.otherMethod
,而是调用obj.dispatch('someMethod')
或obj.dispatch('otherMethod')
,其中dispatch
是包含try
块的包装器然而,你的方法似乎有点奇怪。将对话框内容放在代码的其他部分,更高级别的事件循环捕获错误并显示有关它们的消息可能更有意义。