当我从标准库中获得运行时异常时,它几乎总是我的代码中的问题,而不是库代码中的问题。有没有办法截断异常堆栈跟踪,以便它不显示库包的内容?
例如,我想得到这个:
Traceback (most recent call last):
File "./lmd3-mkhead.py", line 71, in <module>
main()
File "./lmd3-mkhead.py", line 66, in main
create()
File "./lmd3-mkhead.py", line 41, in create
headver1[depotFile]=rev
TypeError: Data values must be of type string or None.
而不是这个:
Traceback (most recent call last):
File "./lmd3-mkhead.py", line 71, in <module>
main()
File "./lmd3-mkhead.py", line 66, in main
create()
File "./lmd3-mkhead.py", line 41, in create
headver1[depotFile]=rev
File "/usr/anim/modsquad/oses/fc11/lib/python2.6/bsddb/__init__.py", line 276, in __setitem__
_DeadlockWrap(wrapF) # self.db[key] = value
File "/usr/anim/modsquad/oses/fc11/lib/python2.6/bsddb/dbutils.py", line 68, in DeadlockWrap
return function(*_args, **_kwargs)
File "/usr/anim/modsquad/oses/fc11/lib/python2.6/bsddb/__init__.py", line 275, in wrapF
self.db[key] = value
TypeError: Data values must be of type string or None.
更新:添加了answer代码,感谢Alex的指针。
答案 0 :(得分:10)
Python标准库中的traceback模块允许您以符合您喜欢的方式发出错误回溯,同时传播异常。您可以在except
/ try
语句的except
段中使用此功能,也可以在已安装为sys.excepthook的功能中使用此功能,该功能会在时间和时间被调用一个异常一直传播;引用文档:
在交互式会话中会发生这种情况 就在控制权返回之前 提示;在这个Python程序中 在程序退出之前发生。 处理这样的顶级 例外可以定制 分配另一个三个参数 函数到sys.excepthook。
这是一个简单的人为例子:
>>> import sys
>>> import traceback
>>> def f(n):
... if n<=0: raise ZeroDivisionError
... f(n-1)
...
>>> def excepthook(type, value, tb):
... traceback.print_exception(type, value, tb, 3)
...
>>> sys.excepthook = excepthook
>>> f(8)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in f
File "<stdin>", line 3, in f
ZeroDivisionError
如您所见,不需要try
/ except
,您可以轻松地将回溯限制为(例如)前三个级别 - 即使我们已经通过设计知道有9个嵌套提出异常时的等级。
你想要比级别上的简单限制更复杂的东西,所以你需要调用traceback.format_exception,它给你一个行列表而不是打印它,然后从那个列表中“修剪”那些行是关于你永远不想在你的追溯中看到的模块,最后发出剩余的行(通常是sys.stderr
,但是,无论如何! - )。
答案 1 :(得分:2)
感谢Alex的指针,这里是代码:
def trimmedexceptions(type, value, tb, pylibdir=None, lev=None):
"""trim system packages from the exception printout"""
if pylibdir is None:
import traceback, distutils.sysconfig
pylibdir = distutils.sysconfig.get_python_lib(1,1)
nlev = trimmedexceptions(type, value, tb, pylibdir, 0)
traceback.print_exception(type, value, tb, nlev)
else:
fn = tb.tb_frame.f_code.co_filename
if tb.tb_next is None or fn.startswith(pylibdir):
return lev
else:
return trimmedexceptions(type, value, tb.tb_next, pylibdir, lev+1)
import sys
sys.excepthook=trimmedexceptions
# --- test code ---
def f1(): f2()
def f2(): f3()
def f3():
import xmlrpclib
proxy = xmlrpclib.ServerProxy('http://nosuchserver')
proxy.f()
f1()
产生此堆栈跟踪:
Traceback (most recent call last):
File "./tsttraceback.py", line 47, in <module>
f1()
File "./tsttraceback.py", line 40, in f1
def f1(): f2()
File "./tsttraceback.py", line 41, in f2
def f2(): f3()
File "./tsttraceback.py", line 45, in f3
proxy.f()
gaierror: [Errno -2] Name or service not known
答案 2 :(得分:1)
Traceback library可能就是你想要的。以下是一个可能有用的示例:
import traceback
try:
your_main()
except:
lines = traceback.format_exc()
print lines[:lines.find('File "/usr')]
(如果库外有异常,这显然不会起作用,可能不完全符合您的需求,但这是使用回溯库的一种方式)
答案 3 :(得分:0)
进行不合格的尝试...除了代码顶部(即:在“主要”中)或设置sys.excepthook
。然后,您可以根据需要格式化堆栈跟踪。