Python 输出详细的异常信息(traceback)方式

  • Post category:Python

当我们在 Python 中编写程序时,经常会遇到程序出现异常的情况。Python 在异常抛出时,会输出一些错误信息。然而,错误信息有时候可能显得不够清晰,难以定位问题的具体出现位置。这时,我们需要使用 Python 的 traceback 模块来输出详细的异常信息。

安装与导入模块

Python 的 traceback 模块是自带的,不需要额外安装。我们只需要在代码中导入该模块即可:

import traceback

使用 traceback 模块

一般来说,我们可以用 try...except... 语句来处理程序的异常。我们在 except 分支中使用 traceback 模块来输出详细的异常信息。

import traceback

try:
    # 可能会出现异常的代码
except Exception as e:
    traceback.print_exc()

上面的代码中,当异常发生时,我们调用 traceback.print_exc() 方法即可输出详细的异常信息。该方法会输出包含异常类型、异常信息以及当前堆栈信息的信息字符串。例如:

Traceback (most recent call last):
  File "test.py", line 4, in <module>
    c = a / b
ZeroDivisionError: division by zero

输出的信息包括了异常类型、异常信息以及当前调用堆栈的信息,能够帮助我们很快精准地定位问题所在。

如果我们想要将异常信息捕获到一个字符串中,可以使用 traceback.format_exc() 方法:

import traceback

try:
    # 可能会出现异常的代码
except Exception as e:
    error_message = traceback.format_exc()

最后,我们还可以将详细异常信息输出到指定的文件中:

import traceback

try:
    # 可能会出现异常的代码
except Exception as e:
    with open('error.txt', 'w') as f:
        traceback.print_exc(file=f)

例子

接下来,我们通过两个例子来说明 traceback 模块的使用。

例子一

我们来看一个最简单的例子。假设我们在编写一个除法程序时,用户可能会输入 0,导致程序出现 ZeroDivisionError 异常。我们使用 traceback 模块来输出详细的异常信息:

import traceback

try:
    a = 10
    b = 0
    c = a / b
except Exception as e:
    traceback.print_exc()

输出结果为:

Traceback (most recent call last):
  File "test.py", line 5, in <module>
    c = a / b
ZeroDivisionError: division by zero

我们可以看到,输出的信息中具体说明了异常类型是 ZeroDivisionError,出现在第 5 行,也就是除法运算处。

例子二

在实际开发中,我们可能会遇到许多复杂的异常情况。下面是一个稍微复杂的例子。假设我们有一个简化版的爬虫程序,需要从若干个网页上爬取数据。我们使用 requests 库来获取网页的 HTML 代码。如果某个网页无法访问,我们将跳过该网页,继续访问下一个。在这个过程中,我们使用 traceback 模块来输出详细的异常信息:

import traceback
import requests

URLS = ['https://www.baidu.com', 'https://www.google.com', 'https://www.notexist.com']

for url in URLS:
    try:
        response = requests.get(url)
        html = response.text
        # 处理网页代码
    except Exception as e:
        print('Error in {}:'.format(url))
        traceback.print_exc()

输出结果为:

Error in https://www.notexist.com:
Traceback (most recent call last):
  File "test.py", line 10, in <module>
    response = requests.get(url)
  File "/usr/local/lib/python3.7/site-packages/requests/api.py", line 75, in get
    return request('get', url, params=params, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/requests/api.py", line 60, in request
    return session.request(method=method, url=url, **kwargs)
  ...
  File "/usr/local/lib/python3.7/site-packages/urllib3/connection.py", line 157, in _new_conn
    (self._dns_host, self.port), self.timeout, **extra_kw)
urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPSConnection object at 0x1079a2048>: Failed to establish a new connection: [Errno 8] nodename nor servname provided, or not known

我们可以看到,在第 10 行发生了异常,由于无法访问该网站,导致 requests 库抛出了异常。在异常信息输出的堆栈信息中,我们还能够看到相关的库代码,以及该异常是由 urllib3 库中的 NewConnectionError 继续引发的。这样一来,定位问题时就会更加方便。

综上,使用 traceback 模块能够帮助我们更好地定位 Python 程序中的异常,为我们的程序调试和维护提供帮助。