python:异常流程:捕获后继续向下捕获块?

时间:2016-11-20 22:49:53

标签: python exception try-catch except

我很好奇如果python中有一种方法可以在try / catch块中继续,在捕获异常后,查看其属性,如果不相关,则继续向下移动。

try:
    # Code
except AppleError as apple_ex:
    # look at 'apple_ex.error_code' error body, and if not relevant, 
    # continue on to next down the catch block...
    # In other words, proceed to except BananaError and so on down.
except BananaError as banana_ex:
    # ...
except Exception as ex:
    # ...

3 个答案:

答案 0 :(得分:2)

这不是Python中处理异常的方式。当您在try块中引发异常时,如果您处理except中的异常,它将落在该块内,但不会继续到同一级别的下一个except。观察这个功能性示例:

try:
    raise AttributeError()
except AttributeError:
    raise TypeError()
except TypeError:
    print("it got caught") # will not catch the TypeError raised above

因此,在您的try中,我们会引发AttributeError,我们会抓住它,然后在TypeError内部引发AttributeError

except TypeError抓住 TypeError

根据您解释问题的方式,您需要重新考虑如何处理异常,看看是否可以确定其他地方的错误处理,并在那里引发错误

例如:

def some_func():
    try:
        thing()
    except SomeException:
        # analyze the exception here and raise the error you *should* raise
        if apple_error_thing:
            raise AppleError
        elif banana_error_thing:
            raise BananaError
        else:
            raise UnknownException


def your_func():
    try:
        some_func()
    except AppleError as e:
        print('Apple')
    except BananaError as e:
        print('Banana')
    except UnknownException as e:
        print('Unknown')

答案 1 :(得分:1)

不,那是不可能的。在内部except处理异常后,它无法由外部except处理:

来自try声明中的the docs

  

当到达此块的末尾时,在整个try语句之后正常继续执行。 (这意味着如果同一个异常存在两个嵌套处理程序,并且内部处理程序的try子句中发生异常,则外部处理程序将不处理异常。)

简而言之,您唯一的解决方案可能是在外层使用另一个处理程序,并在内部处理程序中重新raise异常,即:

try:
    try:
        raise ZeroDivisionError
    except ZeroDivisionError as e:
        print("caught")
        raise ZeroDivisionError
except ZeroDivisionError as f:
    print("caught")

现在,嵌套的except引发了一个异常,因此被类似的处理程序捕获。

答案 2 :(得分:1)

AppleError仍然是AppleError而不是BananaError,即使error_code不相关,因此没有理由落入BananaError。

您可以为不同的错误代码定义特定错误:

GRANNY_SMITH_ERROR = 1
MACINTOSH_ERROR = 2
class AppleError(Exception): 
    def __init__(self, error_code, *args):
        super(AppleError, self).__init__(*args)
        self.error_code = error_code

class GrannySmithError(AppleError):
    def __init__(self, *args):
        super(GrannySmithError, self).__init__(GRANNY_SMITH_ERROR, *args)

class MacintoshError(AppleError):
    def __init__(self, *args):
        super(MacintoshError, self).__init__(MACINTOSH_ERROR, *args)

然后您可以尝试匹配特定错误:

try: raise MacintoshError()
except MacintoshError as exc: print("mac")
except GrannySmithError as exc: print("granny smith")

如果您不想区分不同类型的苹果错误,您仍然可以捕获所有苹果错误:

try: raise MacintoshError()
except AppleError as exc: print("generic apple")

您可以将这些组合起来,例如,仅对GrannySmith进行特殊处理,而不是对Macintosh:

try: raise MacintoshError()
except GrannySmithError as exc: print("granny smith")
except AppleError as exc: print("generic apple")

重要的是列出从最具体到最不具体的错误。如果您在GrannySmithError之前测试AppleError,那么它将永远不会进入GrannySmith块。