如何在异常上退出循环,但不重新引发每个异常类型?

时间:2012-11-28 11:36:22

标签: python exception-handling

我有一个循环,我想在KeyboardInterrupt上终止:

while True:
    try:
        do_stuff()
    except KeyboardInterrupt:
        cleanup()
        break
    except Exception as e:
        cleanup()
        raise e

这很好,但双cleanup()对我来说似乎非常不洁净。我不喜欢重复的代码。我尝试使用上下文管理器,但这引入了许多不必要的复杂性,文件大小几乎翻了一倍。

是否有更清洁的方式表达我的意图?

3 个答案:

答案 0 :(得分:5)

您可以使用BaseException同时抓住

try:
   do_stuff():
except BaseException as e:
    cleanup()
    if isinstance(e, KeyboardInterruption):
        break
    raise e

此外,您只能使用raise代替raise e

答案 1 :(得分:5)

finally关键字正是您所寻找的。 The doc on errors and exceptions解释了它的用法。

  

在离开try语句之前总是执行finally子句,无论是否发生了异常


如果仅在离开循环时发生清理,我建议交换循环并尝试:

try:
    while True:
        do_stuff()
except KeyboardInterrupt:
    pass
finally:
    cleanup()

答案 2 :(得分:1)

听起来你想要finally子句:

while True:
  try:
    do_stuff()
  except KeyboardInterrupt:
    break
  finally:
    cleanup()

cleanup()将始终被调用,无论异常是否被引发或被捕获。