全班的例外情况

时间:2013-10-07 18:52:41

标签: python class exception global

我正在用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中推荐的处理方法是什么?

2 个答案:

答案 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)

我可以想到两个选择:

  1. 编写一个可以包装try块中每个方法的装饰器。
  2. 编写一个“调度程序”方法,在try块中调用适当的方法,然后调用该方法而不是单个方法。也就是说,不是调用obj.someMethod()obj.otherMethod,而是调用obj.dispatch('someMethod')obj.dispatch('otherMethod'),其中dispatch是包含try块的包装器
  3. 然而,你的方法似乎有点奇怪。将对话框内容放在代码的其他部分,更高级别的事件循环捕获错误并显示有关它们的消息可能更有意义。