对所有捕获到的异常执行通用操作的Python方式

时间:2019-03-06 11:23:57

标签: python try-except

如果我具有以下结构:

try:
    do_something_dangerous()
except Exception1:
    handle_exception1()
    handle_all_exceptions()
except Exception2:
    handle_exception2()
    handle_all_exceptions()
...

如果我不想在每个handle_all_exceptions子句中这样做(因为我有很多子句),那么最Python的方式来调用except是什么?也许有一种简单的方法可以确定finally子句中是否发生了异常?

4 个答案:

答案 0 :(得分:4)

我认为最简单的方法是嵌套try语句:

try:
   try:
        do_something_dangerous()
    except Exception1:
        handle_exception1()
        raise
    except Exception2:
        handle_exception2()
        raise
except Exception:
    handle_all_exceptions()

光秃秃的raise会引发异常。

另一种选择是捕获所有异常并进行自己的调度,而不是使用try语句:

try:
    do_something_dangerous()
except Exception as e:
    if isinstance(e, Exception1):
        handle_exception1()
    if isisntance(e, Exception2):
        handle_exception2()
    handle_all_exceptions()

答案 1 :(得分:2)

我认为您还可以检查异常的类型。但是,我不知道这是否是最pythonic的方式:

编辑:在文档中,似乎没有最Python化的方式。如何处理函数handle_all_exceptions()中的不同类型的异常取决于您自己。 See the doc.

try:
    do_something_dangerous()
except Exception as e:
    handle_all_exceptions(e)

def handle_all_exceptions(e):
    if isinstance(e, Exception1):
        handle_exception1()
    elif isinstance(e, Exception2):
        handle_exception2()

由于您不想检查实例或类似实例,因此这是另一种可能的实现方式。尽管列表实现肯定不是很好,但是它解决了没有嵌套try语句的问题。您还可以使用布尔语句或类似的语句,但是使用列表,您仍然可以访问错误对象以进行进一步处理。

ex = []
try:
    do_something_dangerous()
except Exception1 as e:
    ex.append(e)
    handle_exception1()
except Exception2 as e:
    ex.append(e)
    handle_exception2()
finally:
    if ex: handle_all_exceptions(ex)

答案 2 :(得分:1)

You could first define a mapping associating handling function with corresponding exception:

err_handling = {
   Exception1: handle_exception1
   Exception2: handle_exception2
   # ...
}

Then you could accept the raised exception as an argument of the handle_all_exceptions function, and add it the specific handling using the handling mapping and the type of the raised exception.

def handle_all_exceptions(err):
    # common exception handling
    err_handling[type(err)]()

Doing it you could handle you exception in a simple manner:

try:
    do_something_dangerous()
except Exception as err:
    handle_all_exceptions(err)

答案 3 :(得分:0)

我找到了一些棘手的解决方案,每个type子句中都没有isinstanceraise和很多except。也许它不是最Python化的,但至少很有趣:

try:
    do_something_dangerous()
except:
    try:
        raise
    except Exception1:
        handle_exception1()
    except Exception2:
        handle_exception2()
    handle_all_exceptions()