在终端中为Python异常上色

15 投票
4 回答
10578 浏览
提问于 2025-04-17 15:15

有没有简单的方法可以让命令行中的异常信息变成彩色的?比如说:

def g():    f()
def f():    1/0
g()

会出现这样的错误:

Traceback (most recent call last):
  File "test.py", line 3, in <module>
    g()
  File "test.py", line 1, in g
    def g():    f()
  File "test.py", line 2, in f
    def f():    1/0
ZeroDivisionError: integer division or modulo by zero

我希望“整数除以零或取模”这个错误信息在终端上能变成彩色或者突出显示,这样我就能在一长串错误信息中快速找到它(仅限Linux)。理想情况下,我不想为每种异常都写一个自定义类,而是想要一种方法能够捕捉并格式化所有类型的异常。

编辑:评论中链接的问题提供了如何使用外部软件解决这个问题的例子,但我更想要一个内部的Python解决方案。

4 个回答

4

这段话是说,作者把一个解决方案进行了改进,让异常信息的颜色化变成了异常的一部分,而不是让用户自己去给每个异常信息加颜色。显然,这种方法只适用于自定义的异常,所以可能不完全符合提问者的需求。

from colorama import Fore, init
init()

class Error (Exception):
    def __init__ (self, message):
        super().__init__(Fore.RED + message)

class BadConfigFile (Error):
    pass

raise BadConfigFile("some error message")

这段代码会把“某个错误信息”的追踪记录打印成红色。把'Error'作为基类的意思是,你可以创建其他的异常,这些异常都会继承这个信息的颜色化效果。

6

发现了另一种方法,可以使用IPython模块,这个模块大家可能已经安装过了,因为它通常是其他工具的依赖。

from IPython.core.ultratb import ColorTB
c = ColorTB()
exc = sys.exc_info()
print(''.join(c.structured_traceback(*exc)))
23

你可以给 sys.excepthook 处理器 指定一个自定义的函数。每当出现一个没有被处理的错误(也就是导致程序退出的错误)时,这个函数就会被调用。

def set_highlighted_excepthook():
    import sys, traceback
    from pygments import highlight
    from pygments.lexers import get_lexer_by_name
    from pygments.formatters import TerminalFormatter

    lexer = get_lexer_by_name("pytb" if sys.version_info.major < 3 else "py3tb")
    formatter = TerminalFormatter()

    def myexcepthook(type, value, tb):
        tbtext = ''.join(traceback.format_exception(type, value, tb))
        sys.stderr.write(highlight(tbtext, lexer, formatter))

    sys.excepthook = myexcepthook

set_highlighted_excepthook()

这个版本使用了 pygments,可以把错误信息转换成带有ANSI颜色格式的文本,然后再写入 stderr(标准错误输出)。

还有人把这个做成了一个项目,可以检测终端的支持情况,并让你设置 pygments 的样式,详情请见 colored-traceback.py

撰写回答