全班的例外情况

use*_*129 5 python global exception class

我正在用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
Run Code Online (Sandbox Code Playgroud)

随着类的增长,一遍又一遍地编写相同的try-except块有点烦人.是否有可能为全班创造某种"全球"例外?Python中推荐的处理方法是什么?

kin*_*all 9

编写一个或多个异常处理函数,在给定函数和其中引发的异常的情况下,执行您想要执行的操作(例如,显示警报).如果您需要多个,请写下它们.

def message(func, e):
    print "Exception", type(e).__name__, "in", func.__name__
    print str(e)
Run Code Online (Sandbox Code Playgroud)

现在编写一个装饰器,将给定的处理程序应用于被调用的函数:

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

这仅捕获您指定的例外.如果你没有指定任何,Exception就被抓住了.另外,第一个参数可以是两个处理函数的元组(或其他序列); 第二个处理程序,如果给定,则在finally子句中调用.从主处理程序返回的值将作为函数调用的值返回.

现在,鉴于上述情况,您可以写:

@handle_with(message, TypeError, ValueError)
def add(x, y):
    return x + y
Run Code Online (Sandbox Code Playgroud)

您也可以使用上下文管理器执行此操作:

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

现在你可以写:

def message(e):
    print "Exception", type(e).__name__
    print str(e)

 def add(x, y):
     with handler(message, TypeError, ValueError):
         return x + y
Run Code Online (Sandbox Code Playgroud)

请注意,上下文管理器不知道它所处的功能(你可以找到它,sorta,使用inspect,虽然这是"魔术"所以我没有这样做)所以它给你一些不太有用的信息.此外,上下文管理器不会让您有机会在处理程序中返回任何内容.