【问题标题】:Python 'except' fall-throughPython 'except' 失败
【发布时间】:2016-01-17 23:31:55
【问题描述】:

我想知道您是否可以重新引发(特定)捕获的异常,并让它被以后的(一般)捕获,除非在同一个 try-except 中。例如,我想对特定的 IOError 做一些事情,但如果它不是预期的 IOError,那么应该像处理任何其他错误一样处理异常。我最初尝试的:

try:
    raise IOError()
except IOError as ioerr:
    if ioerr.errno == errno.ENOENT:
        # do something with the expected err
    else:
        # continue with the try-except - should be handled like any other error
        raise
except Exception as ex:
    # general error handling code

但是,这不起作用:raise 会在 try-except 的上下文之外重新引发异常。 编写此代码以获得所需的异常“失败”行为的 Pythonic 方式是什么?

(我知道有一个提议的“有条件的除外”没有实现,这本可以解决这个问题)

【问题讨论】:

  • 所以您希望能够从except IOError 块转到except Exception 块?据我所知,这是不可能的,对于给定的try,只有一个except 块(或else 块)运行。您可以将整个东西包裹在另一个 try 中,移除内部的 except Exception,这意味着除了专门处理的 IOErrors 之外的所有内容最终都在外部 tryexcepts 中。
  • 这是我想做的,我担心只有一个 except 是可能的。我希望有一个更优雅的解决方案,比如嵌套 else's/code duplication

标签: python-2.7 exception-handling try-catch


【解决方案1】:

如果您最终希望它捕获所有内容,请让它这样做。先抓,后筛。 ;)

try:
    raise IOError()
except Exception as ex:
    if isinstance(ex, IOError) and ex.errno == errno.ENOENT:
        # do something with the expected err
    # do the rest

【讨论】:

  • 只有当您的期望失败时,您才能将else 语句添加到# do the rest
【解决方案2】:

我不是 Python 编写方面的专家,但我认为一种明显的方法(如果您知道您期待一种特定类型的异常)是使用嵌套异常处理:

try:
    try:
        raise IOError()
    except IOError as ioerr:
        if ioerr.errno == errno.ENOENT:
            # do something with the expected err
        else:
            # pass this on to higher up exception handling
            raise

except Exception as ex:
    # general error handling code

我在您的评论中知道您不想要嵌套 else 的——我不知道嵌套异常处理在您的书中是否一样糟糕,但至少您可以避免代码重复。

【讨论】:

  • 这是一个很好的方法,一旦你看到它就很明显了。很酷的主意!
【解决方案3】:

所以,我在这里做同样的事情,在查看了可用的解决方案之后,我将继续捕获父异常,然后测试细节。就我而言,我正在使用 dns 模块。

try:
    answer = self._resolver.query(name, 'NS')
except dns.exception.DNSException, e:  #Superclass of exceptions tested for
    if isinstance(e, dns.resolver.NXDOMAIN):
        #Do Stuff
    elif isinstance(e, dns.resolver.NoAnswer):
        # Do other stuff
    else:
        # Do default stuff

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-26
    • 1970-01-01
    • 1970-01-01
    • 2017-03-09
    • 1970-01-01
    • 1970-01-01
    • 2011-04-25
    • 1970-01-01
    相关资源
    最近更新 更多