处理任意异常,打印默认异常信息

20 投票
5 回答
12036 浏览
提问于 2025-04-15 17:39

我有一个程序,其中有一部分在执行一个循环。在这个循环执行的过程中,会出现一些错误。显然,我希望我的程序能够顺利运行,不出错,但为了能够处理所有输入,我希望程序在出现错误时不要停止,而是继续执行。实现这个目标最简单的方法就是使用一个 except 块。

但是,当我这样做时,它会捕捉到所有的错误,并继续执行程序,这样我就看不到错误信息了,而这些信息对我调试是很重要的。

有没有办法在 except 块中捕捉到任何错误,并且能够打印出错误信息呢?

5 个回答

9

虽然James的回答几乎总是你想要的,但它并不是OP(原提问者)问的内容:

有没有办法捕获任何任意的异常,并且能够在捕获块中打印出异常信息?

Exception其实并不能处理所有的异常,只是那些你通常想要捕获的异常。特别是在2.5及以后的版本中:

所有内置的、非系统退出的异常都来自这个类。所有用户定义的异常也应该来自这个类。

这就漏掉了一些东西:

  • 内置的系统退出异常,比如用户按下 KeyboardInterrupt(即按下 ^C,仅在2.5及以后版本)
  • 那些不遵循“应该”的用户定义异常

有时候,你确实想处理像 KeyboardInterrupt 这样的情况,这时你需要使用 BaseException 而不是 Exception。 (可以查看 异常层级,了解哪些异常是 Exception 的子类,哪些不是。)所以:

try:
    # stuff
except BaseException as e:
    print e

而且(通常在调试时)有时候你确实想处理所有的异常。在2.7中,这包括被定义为旧式类的异常;在2.5及更早版本中,它还包括字符串。处理所有这些可能性唯一的方法是使用裸 except,然后使用 sys.exc_info(并且可以选择重新抛出你不想处理的异常):

try:
    # stuff
except:
    type, value, traceback = sys.exc_info()
    print value

顺便说一下,我在上面使用的是新的 except 语法(except Exception as e)。这个在2.6及以后的版本,包括3.x中都可以用。旧的语法(except Exception, e)在2.6中被弃用,并在3.0中停止工作,但如果你想在旧的2.x版本中工作,就需要使用它。

12

可以考虑使用Python的日志模块,这样你就能记录问题,以便以后查看。下面是一个简单的例子,展示了如何使用日志模块来记录异常情况:

import logging
LOG_FILE = '/tmp/exceptions.log'
logging.basicConfig(filename=LOG_FILE,level=logging.ERROR)

while True:
try:
    # Code that may throw exceptions
except Exception, e:
    logging.exception("An exception happened")

在异常处理程序中使用logging.exception这个函数,就像这里做的那样,异常的信息会自动添加到日志消息中。

22
try:
    #stuff
except Exception as e:
    print e

traceback模块提供了多种功能,可以从异常对象(上面提到的e)中提取更多信息。

来源:错误和异常

撰写回答