当我从标准库中获得运行时异常时,它几乎总是我的代码中的问题而不是库代码中的问题.有没有办法截断异常堆栈跟踪,以便它不显示库包的内容?
例如,我想得到这个:
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.
Run Code Online (Sandbox Code Playgroud)
而不是这个:
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.
Run Code Online (Sandbox Code Playgroud)
更新:通过Alex的指针添加了代码的答案.
Ale*_*lli 10
Python标准库中的回溯模块允许您以符合您喜欢的方式发出错误回溯,同时传播异常.您可以在使用这个权力或者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
Run Code Online (Sandbox Code Playgroud)
如您所见,不需要try
/ except
,您可以轻松地将回溯限制为(例如)前三个级别 - 即使我们通过设计知道在引发异常时有9个嵌套级别.
你想要比级别上的简单限制更复杂的东西,所以你需要调用traceback.format_exception,它给你一个行列表而不是打印它,然后从那个列表中"修剪"关于模块的行你永远不会想要在你的追溯中看到,最后发出剩余的线(通常是sys.stderr
,但是,无论如何! - ).
感谢 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()
Run Code Online (Sandbox Code Playgroud)
这会产生这个堆栈跟踪:
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
Run Code Online (Sandbox Code Playgroud)