python3: 不要在错误消息中显示完整的目录路径
python3: Don't show full directory path on error message
有没有办法在执行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 = '3[91m'
GREEN = '3[92m'
YELLOW = '3[93m'
LIGHT_PURPLE = '3[94m'
PURPLE = '3[95m'
CYAN = '3[96m'
END = '3[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("")
我认为编写自定义错误的最佳方式是使用 try 和 except。
try:
doSomething() # You code goes here.
except Exception:
# Whatever you want to be shown, full path, anything.
pass
如果您没有 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)
您可以将自定义函数分配给 sys.excepthook
到 handle 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
有没有办法在执行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 = '3[91m'
GREEN = '3[92m'
YELLOW = '3[93m'
LIGHT_PURPLE = '3[94m'
PURPLE = '3[95m'
CYAN = '3[96m'
END = '3[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("")
我认为编写自定义错误的最佳方式是使用 try 和 except。
try:
doSomething() # You code goes here.
except Exception:
# Whatever you want to be shown, full path, anything.
pass
如果您没有 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)
您可以将自定义函数分配给 sys.excepthook
到 handle 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