14

有没有一种简单的方法可以让异常消息在命令行上着色?例如

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 回答 4

19

您可以将自定义函数分配给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.

于 2013-02-08T16:09:05.200 回答
5

使用 IPython 模块找到了另一种方法,这可能是每个人都已经安装的依赖项:

from IPython.core.ultratb import ColorTB
c = ColorTB()
exc = sys.exc_info()
print(''.join(c.structured_traceback(*exc)))
于 2016-12-05T18:40:57.740 回答
2

看看colorama(或任何其他着色)模块。然后你可以用以下方式包装你的整个应用程序:

import traceback
from colorama import Fore, init
init( )

try:
    // your app
except Exception:
    print Fore.RED + traceback.format_exc( ) + Fore.RESET
    // possibly raise again or log to db
于 2013-02-08T15:48:29.083 回答
2

这采用了@freakish 共享的解决方案并使着色成为异常的一部分,而不是要求用户为每个异常消息添加颜色。显然,它只适用于自定义异常,所以它可能不是 OP 想要的。

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

这将以红色打印带有“一些错误消息”的回溯。将“错误”作为基类意味着您可以创建其他将全部继承消息颜色的异常。

于 2019-10-14T14:46:23.037 回答