在python 3.6中,如何捕获异常并引发异常以便以后处理?

时间:2018-12-14 16:53:42

标签: python python-3.x exception exception-handling

假设我有2个例外:

class FooError (Exception):
    def __init__(self, *args, **kwargs):
        default_message = 'A foo error has occurred!'
        if not (args or kwargs): args = (default_message,)
        super().__init__(*args, **kwargs)
class BarError (Exception):
    def __init__(self, *args, **kwargs):
        default_message = 'A bar error has occurred!'
        if not (args or kwargs): args = (default_message,)
        super().__init__(*args, **kwargs)

而且,我有一个抛出FooError的函数:

def foobar (x):
    if x < 0:
        raise FooError()

通常,您可以使用FooError块来处理try/except

try:
    foobar(-1)
except FooError:
    print('Uh oh, foo error!')
    sys.exit()

但是,我想抛出一个BarError,我以后可以处理。像这样:

except BarError:
    print('Uh oh, bar error!')
    sys.exit()

但是,执行此操作时,我只是获得了两个错误的回溯:

Traceback (most recent call last):
  File "C:\Users\Maze\Desktop\test2.py", line 17, in <module>
    foobar(-1)
  File "C:\Users\Maze\Desktop\test2.py", line 15, in foobar
    raise FooError()
__main__.FooError: A foo error has occurred!

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\Maze\Desktop\test2.py", line 19, in <module>
    raise BarError()
__main__.BarError: A bar error has occurred!

如何将BarError扔到FooError的处理程序中,然后在另一个BarError块中处理except

3 个答案:

答案 0 :(得分:1)

不确定我是否理解您的要求,但是您可以在其他异常处理程序中轻松引发新的异常:

def call_foobar():
    try:
        foobar(-1)
    except FooError:
        print('Uh oh, foo error!')
        raise BarError()

try:
    call_foobar()
except BarError as e:
    print("Bar Error")

您不必为此提供功能,也可以嵌套两个try块。

这能回答您的问题吗?

答案 1 :(得分:1)

不能。一旦捕获到异常,就无法将控制权转移到相同 except语句中的另一个try块。您可以使用嵌套语句:

try:
    try:
        foobar(-1)
    except FooError:
        raise BarError
except BarError:
    print('Uh oh, bar error!')
    sys.exit()

如果要区分由BarError直接引发的foobar和由于BarError被捕获而引起的FooError之间的区别,则需要做一些额外的工作。您可以为此使用异常链接。有关更多详细信息,请参见PEP-3134;此示例可能不是编写此示例的最佳方法。

try:
    try:
        foobar(-1)
    except FooError as exc:
        raise BarError from exc
except BarError as exc:
    if isinstance(exc.__cause__, FooError):
        print("Caught a Foo-induced BarError")
    else:
        print("Caught a regular BarError")

答案 2 :(得分:0)

听起来好像您想捕获FooErrorBarError,但是如果它是FooError,则要先做一些额外的工作。在这种情况下,您可以捕获两种异常,并且只对FooError起作用:

try:
    foobar(-1)
except (FooError, BarError) as e:
    if isinstance(e, FooError):
        # do extra work
    # Handle errors