【问题标题】:python3: Don't show full directory path on error messagepython3:不显示错误消息上的完整目录路径
【发布时间】:2016-08-31 14:50:11
【问题描述】:

有没有办法在执行python程序时只显示重要的目录路径?

目前我明白了:

python3 foo.py                                        
Traceback (most recent call last):
  File "foo.py", line 60, in <module>
    foo = Foo()
  File "foo.py", line 22, in __init__
    self._run()
  File "/media/MyDocuments/xxxxxxx/yyyyyyyyy/python_code/foo.py", line 18, in check_input
    bar = obj.get_action()
AttributeError: 'obj' object has no attribute 'get_action'

据我所知,我的代码在哪个目录中,完整的目录会使错误消息的可读性更差。我可以告诉 python 显示更多这样的输出吗?

python3 foo.py                                        
    Traceback (most recent call last):
      File "foo.py", line 60, in <module>
        foo = Foo()
      File "foo.py", line 22, in __init__
        self._run()
      File ".../foo.py", line 18, in check_input
        bar = obj.get_action()
    AttributeError: 'obj' object has no attribute 'get_action'

回答

使用 unutbu 中的代码,我添加了一些颜色行,以防有人正在寻找对解释器输出的简单改进,只需将其用作模块并导入即可:

import sys
import traceback
import os
import re

RED = '\033[91m'
GREEN = '\033[92m'
YELLOW = '\033[93m'
LIGHT_PURPLE = '\033[94m'
PURPLE = '\033[95m'
CYAN = '\033[96m'
END = '\033[0m'

def my_excepthook(type, value, tb):
    lines = traceback.format_list(traceback.extract_tb(tb))
    def shorten(match):
        return 'File "{}"'.format(os.path.basename(match.group(1)))
    lines = [re.sub(r'File "([^"]+)"', shorten, line) for line in lines]
    _print_color(lines)
    # print(''.join(lines))
    print(RED + '{}: {}'.format(type.__name__, value) + END)

sys.excepthook = my_excepthook


def _print_color(lines):
    for l in lines:
        for i in range(len(l)-1):
            if l[i:i+5]=="line ":
                i +=5
                # Find the length of the number
                numLen = 0
                while l[i+numLen].isdigit():
                    numLen +=1

                # Find the length of the function
                funLen = 0
                while not l[i+numLen+4 + funLen]=="\n":
                    funLen+=1

                l = ''.join([l[:i],
                        YELLOW+"{}".format(l[i:i+numLen])+END,
                        l[i+numLen:i+numLen+5],
                        LIGHT_PURPLE+"{}".format(l[i+numLen+5:i+numLen+5+funLen])+END,
                        CYAN+"{}".format(l[i+numLen+5+funLen:])+END])
                print(l,end="")
                break
    print("")

【问题讨论】:

  • 你能提供一个简短而完整的程序来产生这样的消息吗?我无法重现您的结果 - 我所有的回溯都说“foo.py”,就像您的回溯的前两行一样。
  • 我所有的代码都保存在同一个目录中,所以任何示例都会在我的计算机上产生这种错误消息。我正在使用 Ubuntu,python3,也许另一个操作系统使用不同的标准 python 解释器。

标签: python python-3.x compiler-errors output


【解决方案1】:

您可以将自定义函数分配给sys.excepthookhandle all uncaught exceptions

sys.excepthook = my_excepthook

那么你可以使用

def my_excepthook(type, value, tb):
    lines = traceback.format_list(traceback.extract_tb(tb))
    # process/modify lines
    print(''.join(lines))

以一行行​​的形式获取回溯错误消息,然后根据需要进行修改和打印。


例如,如果您希望将所有文件路径缩短为其基本名称,您可以使用:

import sys
import traceback
import os
import re

def my_excepthook(type, value, tb):
    lines = traceback.format_list(traceback.extract_tb(tb))
    def shorten(match):
        return 'File "{}"'.format(os.path.basename(match.group(1)))
    lines = [re.sub(r'File "([^"]+)"', shorten, line, 1) for line in lines]
    print(''.join(lines))
    print('{}: {}'.format(type.__name__, value))

sys.excepthook = my_excepthook   # comment this out to see the difference

class Foo():
    def run(self):
        1/0

foo = Foo()
foo.run()

产生

  File "script.py", line 24, in <module>
    foo.run()
  File "script.py", line 21, in run
    1/0

ZeroDivisionError: division by zero

而不是

Traceback (most recent call last):
  File "/home/unutbu/pybin/script.py", line 24, in <module>
    foo.run()
  File "/home/unutbu/pybin/script.py", line 21, in run
    1/0
ZeroDivisionError: division by zero

【讨论】:

  • 谢谢,覆盖系统方法效果很好。我用你的代码创建了我自己的模块。所以我只需要一行来导入这个模块并且没有代码开销。太好了!
【解决方案2】:

如果您没有main 例程,您可以在您的main 过程或最顶层设置一个try except 块。在except 块中,您可以使用traceback 模块解析异常跟踪以删除目录名称和其他非重要信息。

import traceback
import sys
if __name__ == '__main__':
    try:
        #SomeOperation
        #More operation
    except:
        errorMsg = traceback.format_exc()
        #Format error message according to your preference
        print(errorMsgTransformed)
        sys.exit(1) 

【讨论】:

    【解决方案3】:

    我认为编写自定义错误的最佳方法是使用 try 和 except。

    try:
        doSomething() # You code goes here.
    except Exception: 
        # Whatever you want to be shown, full path, anything.
        pass
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-24
      • 1970-01-01
      • 1970-01-01
      • 2017-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多