如何在Python提示符下获取最后的异常对象?

73 投票
3 回答
38628 浏览
提问于 2025-04-17 20:11

在调试Python代码的时候,特别是在交互式提示符(REPL)下,我经常会写一些代码,这些代码会引发错误,但我没有用try/except把它包起来,所以一旦出现错误,我就再也找不到那个错误对象了。

有时候,Python打印出来的错误追踪信息和错误消息并不足够。例如,当你请求一个网址时,服务器可能会返回一个40x的错误,这时候你需要通过error.read()来获取响应的内容……但你已经没有那个错误对象了。比如:

>>> import urllib2
>>> f = urllib2.urlopen('http://example.com/api/?foo=bad-query-string')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  ...
urllib2.HTTPError: HTTP Error 400: Bad Request

哎呀,响应的内容到底说了什么?里面可能有很重要的错误信息……

我意识到,通常重新运行代码并用try/except包起来是很简单的,但这并不是最理想的解决办法。我也明白,在这种特定情况下,如果我使用requests库(它不会因为HTTP错误而抛出异常),我就不会遇到这个问题……但我真的在想,是否有更通用的方法可以在Python提示符下获取最后一个错误对象呢?

3 个回答

1

sys.last_typesys.last_valuesys.last_traceback 这几个变量并不是总是有值的。其实,它们主要是用在交互式会话中的。我可以通过 sys.exc_info() 来获取最后发生的异常。用法如下:

import sys
ex_type, ex_value, traceback = sys.exc_info()

最后发生的异常对象会被存储在 ex_value 里。

34

正如 @Cairnarvon 提到的,我没有在 sys 模块中找到任何 last_value 这个成员。

我用 sys.exc_info() 解决了这个问题。这个函数会返回一个包含三个值的元组 (type, value, traceback)

所以 sys.exc_info()[1] 会给出可读的错误信息。下面是一个例子,

import sys
list = [1,2,3,4]
try:
    del list[8]
except Exception:
    print(sys.exc_info()[1])

会输出 list assignment index out of range,意思是列表赋值时索引超出了范围。

另外,traceback.format_exc() 这个来自 traceback 模块的函数也可以用来打印类似的信息。

如果使用 format_exec(),下面是输出的内容,

Traceback (most recent call last):
  File "python", line 6, in <module>
IndexError: list assignment index out of range
90

sys模块提供了一些函数,可以帮助我们在出现错误后进行检查。这些函数包括:sys.last_typesys.last_valuesys.last_traceback

如果你在找一个特定的函数,那就是sys.last_value

撰写回答