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

In python 3.6, how do I catch an exception and raise an exception to be handled later?

假设我有 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()

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

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 的处理程序中,然后在不同的 except 块中处理 BarError

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

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 块也是可能的。

这是否回答了您的问题?

听起来你想抓住 FooErrorBarError,但如果它是 FooError,你想先做一些额外的工作。如果是这种情况,您可以捕获这两种异常并且只为 FooError:

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

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

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

如果您想区分由 foobar 直接引发的 BarError 和由于 FooError 被捕获而引发的 BarError 之间的区别,则需要一些额外的工作.您可以为此使用异常链接。有关详细信息,请参阅 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")