用 PrettyError优雅的处理Python错误信息

来自:简讯Alfred

大家有没有觉得编程更像是这样一种行为,我们可能会用 20% 的时间将想法写入代码,然后用 80% 的时间来清除错误和修复漏洞。错误信息肯定是我们每天都会看到的,信息可能非常冗长,这样很难区分不同的部分并快速找到我们需要的信息堆栈跟踪有时也过于复杂,难以理解。此外,除非我们覆盖异常类,否则也很难自定义错误信息,这可能又会让人不知所措。

在本文中,我将介绍一个名为 PrettyError 的库,它可以帮助我们解决上述所有痛点以及更多问题。它有许多很酷的功能,可以简化我们的调试过程,帮助我们在编码工作中节省大量时间。

1. 安装和快速启动

像往常一样,安装 PrettyError 库非常简单。我们只需运行 pip 从 PyPI 获取即可。

pip install pretty_errors

快速入门

这可能是最快捷的快速入门指南。当我们想使用默认配置的程序库时,只需在编码前导入即可。

import pretty_errors

现在,让我们定义一个不带 try-except 的函数,以便以后手动创建一些错误。

def divide(a, b):
    return a / b

那么,让我们先看看没有 Pretty Errors 时的情况。我们将模拟除以零的错误。

divide(10)

这就是 Python 中的原始错误信息。然后,让我们通过简单的导入来启用 Pretty Error,并再次运行代码。

import pretty_errors

divide(10)

它已用颜色编码,并配有简化的指示器,如 stdin 和函数名称分隔符。

由于本文篇幅所限,无法演示颜色代码在实践中的作用。下图是 GitHub README 中的截图。

在上述场景中,您喜欢左边的(原始)还是右边的(高亮错误)?

2. 主要特点

该库能做的远不止我们在快速入门中展示的这些。在本节中,我将挑选一些关键功能进行演示。

2.1 配置颜色代码

PrettyError 允许我们自定义颜色代码。

例如,让我们在 Python 脚本文件 app.py 中输入以下代码。

import pretty_errors

open("non_existent_file.txt")

然后,让我们运行这个脚本看看会发生什么。

以上就是 PrettyError 中的默认颜色代码。如果我们想自定义代码呢?很简单,只需使用 pretty_error 模块中的 configure() 函数,如下所示。

import pretty_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")

让我们再次运行这个脚本文件。

有 16 种不同的错误信息输出类型,如 function_color、code_color 和 syntax_error_color,PrettyError 可以对它们进行自定义。

此外,你可能会注意到我使用了 PrettyError 提供的默认颜色枚举。共有 9 种不同的主色调,包括黑色、灰色、红色、绿色、黄色、蓝色、金黄色、青色和白色。每种颜色还带有前缀 BRIGHT_ 和后缀 _BACKGROUND,因此我们可以使用一系列不同的默认颜色。

除此之外,你可能会注意到我在上述配置代码中使用了组合颜色。

pretty_errors.RED_BACKGROUND + pretty_errors.BRIGHT_WHITE

这也是允许的,因此背景色和字体色可以一起用于特定的信息类型。由此可见,如果我们想自定义错误信息,PrettyError 提供了足够多的颜色代码选项。

2.2 添加时间戳

原始 Python 错误信息的一个缺点是不能在显示错误的同时显示时间戳。当然,常见的解决方案是在程序中添加日志模块。

但是,如果程序在完全未捕获和未知异常的情况下崩溃,日志记录解决方案通常也无法实现。此外,有时我们可能出于某种原因想使用一些轻量级的解决方案。

当然,只需添加以下配置,PrettyError 就能做到这一点。

import pretty_errors

pretty_errors.configure(
    display_timestamp=1
)

open("non_existent_file.txt")

配置 display_timestamp 将在显示错误的同时显示一个时间戳,如下所示。

时间戳是 perf_counter 并不完全适合人类阅读。还有一种配置可以帮助我们自定义时间戳功能。下面是一个使用 datetime 模块获取当前时间戳的示例。由于配置将函数作为参数,因此最简单的方法就是传递一个 lambda 函数。

import pretty_errors
import datetime

pretty_errors.configure(
    display_timestamp=1,
    timestamp_function=lambda: datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
)

open("non_existent_file.txt")

当然,如果您想要非常个性化的时间格式,最好在配置之前定义函数,然后只传递函数名。

2.3 在错误中显示更多代码

原始 Python 错误信息的另一个限制是,它只能显示出错的代码行。在发生错误的代码之前的其他代码可能是导致错误的关键因素。除此之外,显示后面的代码也很有用,这样我们就能知道如果错误没有发生,将执行什么代码。

这可以在 PrettyError 中使用 lines_before 和 lines_after 配置来实现。

import pretty_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)
def calculate(x):
    return 1 / x
# The output should show this comment (lines after)
# The output shouldn't show this comment (lines after)

def wrapper():
    calculate(0)

wrapper()

请关注上述代码片段中的注释。根据配置前后的行数,我添加了一些注释,以显示错误信息中应显示哪一行代码。

我们还可以控制跟踪堆栈的级别。有时,当我们不关心主方法之前的堆栈情况时,这个功能会非常有用。因此,我们可以简化错误信息,帮助我们关注错误发生的具体位置。

这可以通过配置项 stack_depth 来实现。

import pretty_errors

pretty_errors.configure(
    stack_depth=1
)

def calculate(x):
    return 1 / x

def wrapper():
    calculate(0)

wrapper()

因此,现在的堆栈深度更小了。

2.4 显示变量值

这是 Python 中最受欢迎的错误信息之一,但在原来的错误信息中却不见踪影。在开发过程中,当我们处理大多数 bug 时,经常需要使用调试工具来重现问题。

如果错误信息能告诉你变量的值是多少呢?也许在大多数情况下,我们可以直接排除故障!

在 PrettyError 中启用这一功能也非常简单,我们可以将 display_locals 配置项设置为 1。

import pretty_errors

pretty_errors.configure(
    display_locals=1  # Enable the display of local variables
)

def calculate_divide(x, y):
    return x / y

calculate_divide(10)

让我们运行这个脚本看一看。

错误信息告诉我们这是一个 ZeroDivisionError。如果我们查看变量 x 和 y 的输出,就会发现 y 的值为 0。

3.环境方面的最佳做法

实际上,我们有时可能希望错误信息非常冗长,但并非总是如此。就上文介绍的功能而言,在不同的环境中,启用或禁用这些功能的偏好也会有所不同。

因此,我们建议利用环境变量来控制 PrettyError 的行为。下面是一个例子。

import pretty_errors
import os

# Configure PrettyErrors based on the environment
if os.getenv('ENV') == 'development':
    pretty_errors.configure(
        stack_depth=0,  # Show full stack
        display_locals=1  # Show local variables in development
    )
else:
    pretty_errors.configure(
        stack_depth=1,  # Show only 3 levels depth
        display_locals=0  # Hide local variables in production
    )

# Main Program
def calculate(x):
    return 1 / x

def wrapper():
    calculate(0)

wrapper()

让我们用不同的环境变量运行脚本。请注意,如果使用的是 Windows 操作系统,则应使用 set ENV=development。当然,使用这种方法,您还可以针对不同的环境进行其他定制和配置。

在本文中,我介绍了 PrettyError。它旨在修正 Python 错误信息中存在的一些限制,确保错误信息更易于理解,从而提高开发和调试效率。它有许多有用的功能,如彩色编码、包含时间戳、显示变量值和自定义堆栈跟踪。当然,作为一种调试工具,我们可能需要考虑是否希望它在所有环境下都能工作。因此,可以引入环境变量来解决这个问题。

加入知识星球【我们谈论数据科学】

600+小伙伴一起学习!



相关推荐

  • [开源]企业级快速开发框架,低代码、跨平台、简单快捷、开箱即用
  • 通用AI Agent里程碑!谷歌打造游戏“神队友”,操作像人,会600项技能
  • Sora将于年内推出拟增加语音功能
  • OpenAI机器人活了!说话做事太像人,2分半视频震撼世界
  • 透过科大讯飞的“AI+”行业实地战,看中国新质生产力变革的未来之路
  • 文献回顾与文献综述的区别是什么?
  • 小红书女装投放,这个玩法朴素,但也能投20万,收回来400万
  • 关于粉丝迁移至本公众号的说明
  • 五星门店小程序性能优化实践
  • ECMAScript 2024(ES15)将带来这些新特性,超实用!
  • UC伯克利:用大模型预测未来,准确率超越人类!
  • 今日arXiv最热NLP大模型论文:大模型把《算法导论》学明白了!
  • Open AI 八年前的设想被谷歌突破啦!DeepMind官宣SIMA,动动嘴就能完成复杂游戏任务
  • AI和人类的共同进化:ChatGPT负责人OpenAI副总裁现场访谈 | 精华与全文
  • Meta公布Llama 3训练集群细节!储备60万块H100迎接AGI
  • 首次攻克「图基础模型」三大难题!港大开源OpenGraph:零样本学习适配多种下游任
  • 4万亿晶体管5nm制程,全球最快AI芯片碾压H100!单机可训24万亿参数LLM,Llama 70B一天搞定
  • 全球首个OpenAI机器人诞生!Figure 01碾压马斯克擎天柱,10亿机器人大军正式启动
  • 阿里数赛首次向AI开放!知乎网友:给AI捏了把汗,该防止人类替考
  • 开源!工厂数字化项目会用到的地理信息系统