原文:
towardsdatascience.com/one-line-of-code-to-say-goodbye-to-confusing-python-error-messages-8090ee6dd046
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/f2c6baaf47b17b80e7b345c769f6217e.png
图片由 15548337 提供,来自 Pixabay
编程是一项活动,我们可能用 20% 的时间将想法写成代码,然后用 80% 的时间来清除错误和修复错误。错误信息肯定是我们在日常生活中会看到的东西。然而,你有没有遇到过 Python 错误信息的困难?
例如,错误信息可能非常冗长,这并不坏,但很难区分不同的部分并快速找到我们需要的信息。堆栈跟踪有时也过于复杂和令人难以理解。除非我们覆盖异常类,否则自定义错误信息也不容易,这可能会再次变得复杂。
在这篇文章中,我将介绍一个名为 PrettyError 的库,它可以帮助我们解决上述所有痛点以及更多。它有许多酷炫的功能,可以简化我们的调试过程,并在编码工作中帮助我们节省大量时间。
1. 安装与快速入门
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/688b0dc5aa430995a225df3f20293ed3.png
图片由 Pexels 提供,来自 Pixabay
如同往常,安装 Pretty Error 库非常简单。我们只需简单地运行pip从 PyPI 获取它。
pip install pretty_errorshttps://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/d79387732e5f727d0c0a3220fb92ce89.png
快速入门
这可能是最快的快速入门指南。当我们想使用库的默认配置时,我们只需要在编码之前导入它。
importpretty_errors现在,让我们定义一个不带 try-except 的函数,这样我们稍后就可以手动创建一些错误。
defdivide(a,b):returna/b那么,让我们首先看看没有 Pretty Errors 时的样子。我们将模拟一个除以零的错误。
divide(1,0)https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/bb0b8e8ce0c44e9b4a63e9610f243f15.png
这是 Python 中的原始错误信息。然后,让我们通过简单地导入它并再次运行代码来启用 Pretty Error。
importpretty_errors divide(1,0)https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/d1a5aecce8d1b70162ca9ae01dac09ce.png
它已经进行了颜色编码,并带有简化的指示符,例如stdin和函数名divide。
由于本文博客的限制,演示颜色代码在实际应用中的实用性并不实际。下面是一个来自 GitHub README 的截图,如图所示。
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/6dd362b4387dd4f083a55e05bcdf0e66.png
图片来源:raw.githubusercontent.com/onelivesleft/PrettyErrors/master/example.png
在上述场景中,你喜欢左边的(原始)还是右边的(Pretty Error)? 😃
3. 关键特性
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/c1bce2f5acff04d57e5ff1ff939269e5.png
图片来源:Robert Owen-Wahl 来自 Pixabay
当然,图书馆的功能远不止我们在快速入门中展示的。在本节中,我将挑选一些关键特性进行演示。
2.1 颜色代码的配置
颜色代码确实使错误消息更容易阅读,毫不奇怪,PrettyError 允许我们自定义颜色代码。
例如,让我们将以下代码放入一个 Python 脚本文件app.py中。
importpretty_errorsopen("non_existent_file.txt")然后,让我们运行这个脚本看看会发生什么。
$ python app.pyhttps://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/c827e12829c7fc4a643f95873ab7fa03.png
好的,上面是 PrettyError 的默认颜色代码。如果我们想自定义代码呢?这很简单,只需在pretty_error模块中使用configure()函数,如下所示。
importpretty_errors pretty_errors.configure(line_color=pretty_errors.BRIGHT_RED,exception_color=pretty_errors.BRIGHT_MAGENTA,exception_arg_color=pretty_errors.CYAN,exception_file_color=pretty_errors.RED_BACKGROUND+pretty_errors.BRIGHT_WHITE)open("non_existent_file.txt")让我们再次运行这个脚本文件。
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/3cdb6b47ec6eae1520eebfdadb778452.png
有 16 种不同的错误消息输出类型,如function_color、code_color和syntax_error_color,PrettyError 可以自定义它们所有。
此外,你可能还会注意到我使用了 PrettyError 提供的默认颜色枚举。包括BLACK、GREY、RED、GREEN、YELLOW、BLUE、MAGENTA、CYAN和WHITE在内的 9 种不同的主要颜色。每种颜色也都有前缀BRIGHT_和后缀_BACKGROUND,因此我们有多种不同的默认颜色可供使用。
除了这些,你可能还会注意到我在上面的配置代码中使用了组合颜色。
pretty_errors.RED_BACKGROUND+pretty_errors.BRIGHT_WHITE这也是允许的,因此背景和字体颜色可以一起用于特定的消息类型。可以看出,如果我们想自定义错误消息,PrettyError 提供了足够的颜色代码选项。
2.2 添加时间戳
原始 Python 错误消息的一个缺点是它不会显示与错误一起的时间戳。当然,常见的解决方案是将日志模块添加到程序中。
然而,如果程序因完全未捕获和未知的异常而崩溃,日志解决方案通常也不会发生。有时,我们可能只是因为某些原因而想要使用一些轻量级的解决方案。
当然,PrettyError 可以通过简单地添加以下配置来实现这一点。
importpretty_errors pretty_errors.configure(display_timestamp=1)open("non_existent_file.txt")配置项display_timestamp将显示错误信息的同时显示时间戳,如下所示。
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/3d272acb87e6f43635e9ff9e906ed1ca.png
但等等,时间戳是perf_counter,这并不太适合人类阅读。别担心,还有一个配置可以帮助我们自定义时间戳函数。以下是一个使用datetime模块获取当前时间戳的示例。由于配置项接受一个函数作为参数,最简单的方法是传递一个 lambda 函数。
importpretty_errorsimportdatetime pretty_errors.configure(display_timestamp=1,timestamp_function=lambda:datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))open("non_existent_file.txt")https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/236a4ebd8028800fef16d367b0d7a3a9.png
当然,如果你想要一个非常定制的时间格式,定义函数并在配置之前传递函数名可能是个好主意。
2.3 在错误中显示更多代码
原始 Python 错误信息的另一个限制是它只显示出现错误的代码行。
有时,这可能还不够,因为错误发生之前的其他代码可能是错误的关键因素。除此之外,显示之后的代码也可能很有用,这样我们就可以知道如果错误没有发生,将会执行什么。
是的,在 PrettyError 中使用配置lines_before和lines_after是可以做到的。
importpretty_errors pretty_errors.configure(lines_before=2,lines_after=1)# The output shouldn't show this comment (lines before)# The output should show this comment (lines before)defcalculate(x):return1/x# The output should show this comment (lines after)# The output shouldn't show this comment (lines after)defwrapper():calculate(0)wrapper()请注意上述代码片段中的注释。基于前后行配置,我在代码中添加了一些注释,以显示错误信息中应该显示到哪一行代码。
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/3d908047be147ee6e58c5432ac22f406.png
此外,注意那个跟踪堆栈?我们也可以控制跟踪堆栈的级别。有时当我们不关心堆栈直到main方法的情况时,这个功能会非常有用。因此,我们可以简化错误信息,以便我们能够专注于错误确实发生的地方。
这可以通过配置项stack_depth来实现。
importpretty_errors pretty_errors.configure(stack_depth=1)defcalculate(x):return1/xdefwrapper():calculate(0)wrapper()https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/b460471e5b8ba08b5036c05aa2fea6cd.png
现在,堆栈深度减少了。
2.4 显示变量值
我敢打赌,这可能是 Python 中最期望的错误信息之一,但在原始版本中却缺失了。当我们处理开发过程中的大部分错误时,我们通常必须使用调试工具来尝试重现问题。
如果错误信息可以告诉你变量的值会怎样?也许在大多数场景中,我们可以直接排查问题!
在 PrettyError 中启用此功能也非常简单,我们可以将配置项display_locals设置为 1。
importpretty_errors pretty_errors.configure(display_locals=1# Enable the display of local variables)defcalculate_divide(x,y):returnx/y calculate_divide(1,0)让我们运行这个脚本并看看。
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/d93d0aed4964647fc1e22c6ecc80a3e3.png
错误信息告诉我们这是一个ZeroDivisionError。如果我们检查变量x和y的输出,我们可以看到y的值为 0。因此,启用此功能后,调试效率将更高。
3. 环境中的最佳实践
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/8cfd23aa0b0649b5fadfecdf57d9ee91.png
图片由YeriLee在Pixabay提供
在实践中,我们有时可能希望错误信息非常详细,但并非总是如此。就上述功能而言,在不同环境中启用或禁用它们的偏好可能会有所不同。
因此,建议我们利用环境变量来控制 PrettyError 的行为。以下是一个示例。
importpretty_errorsimportos# Configure PrettyErrors based on the environmentifos.getenv('ENV')=='development':pretty_errors.configure(stack_depth=0,# Show full stackdisplay_locals=1# Show local variables in development)else:pretty_errors.configure(stack_depth=1,# Show only 3 levels depthdisplay_locals=0# Hide local variables in production)# Main Programdefcalculate(x):return1/xdefwrapper():calculate(0)wrapper()让我们使用不同的环境变量运行脚本。结果如下所示。
请注意,如果您使用的是 Windows 操作系统,应使用set ENV=development。
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/efc95fa9d1435fd6671c87e9512a8190.png
当然,您可以使用这种方法为不同的环境进行任何其他自定义和配置。
摘要
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/59bcb44c8b15d90814fd783f21de4f11.png
图片由Hans在Pixabay提供
在本文中,我介绍了 PrettyError。它旨在修复 Python 错误信息中存在的某些限制,以确保错误信息更加易于理解,从而提高开发和调试效率。
有许多有用的功能,例如颜色编码、包含时间戳、显示变量值和可定制的堆栈跟踪。当然,作为一个调试工具,我们可能需要考虑是否希望它在所有环境中工作。因此,可以引入环境变量来解决这个问题。
如果您对这个库感兴趣,可以在这里查看。
GitHub – onelivesleft/PrettyErrors: Prettify Python exception output to make it legible.
除非另有说明,所有图片均由作者提供