搞清楚 Python traceback

. Python中的异常栈跟踪

之前在做Java的时候,异常对象默认就包含stacktrace相关的信息,通过异常对象的相关方法printStackTrace()和getStackTrace()等方法就可以取到异常栈信息,能打印到log辅助调试或者做一些别的事情。但是到了Python,在2.x中,异常对象可以是任何对象,经常看到很多代码是直接raise一个字符串出来,因此就不能像Java那样方便的获取异常栈了,因为异常对象和异常栈是分开的。而多数Python语言的书籍上重点在于描述Python中如何构造异常对象和raise try except finally这些的使用,对调试程序起关键作用的stacktrace往往基本上不怎么涉及。

python中用于处理异常栈的模块是traceback模块,它提供了print_exception、format_exception等输出异常栈等常用的工具函数。

def func(a, b):

returna / b

if__name__ =='__main__':

importsys

importtraceback

try:

func(1,0)

exceptExceptionase:

print"print exc"

traceback.print_exc(file=sys.stdout)

输出结果:

print exc

Traceback (most recentcalllast):

File"./teststacktrace.py", line7,in

func(1,0)

File"./teststacktrace.py", line2,infunc

return  a / b

其实traceback.print_exc()函数只是traceback.print_exception()函数的一个简写形式,而它们获取异常相关的数据都是通过sys.exc_info()函数得到的。

def func(a, b):

returna / b

if__name__ =='__main__':

importsys

importtraceback

try:

func(1,0)

exceptExceptionase:

print"print_exception()"

exc_type, exc_value, exc_tb = sys.exc_info()

print'the exc type is:', exc_type

print'the exc value is:', exc_value

print'the exc tb is:', exc_tb

traceback.print_exception(exc_type, exc_value, exc_tb)

输出结果:

print_exception()

the exc typeis:

the exc valueis:integerdivisionormodulobyzero

the exc tbis:

Traceback (most recentcalllast):

File"./teststacktrace.py", line7,in

func(1,0)

File"./teststacktrace.py", line2,infunc

return  a / b


sys.exc_info()返回的值是一个元组,其中第一个元素,exc_type是异常的对象类型,exc_value是异常的值,exc_tb是一个traceback对象,对象中包含出错的行数、位置等数据。然后通过print_exception函数对这些异常数据进行整理输出。

traceback模块提供了extract_tb函数来更加详细的解释traceback对象所包含的数据:

def func(a, b):

returna / b

if__name__ =='__main__':

importsys

importtraceback

try:

func(1,0)

except:

_, _, exc_tb = sys.exc_info()

forfilename, linenum, funcname, sourceintraceback.extract_tb(exc_tb):

print"%-23s:%s '%s' in %s()"% (filename, linenum, source, funcname)

输出结果:

samchimac:tracebacktest samchi$ python ./teststacktrace.py ./teststacktrace.py    :7'func(1,0)'in()./teststacktrace.py    :2'returna / b'infunc()

2. 使用cgitb来简化异常调试

如果平时开发喜欢基于log的方式来调试,那么可能经常去做这样的事情,在log里面发现异常之后,因为信息不足,那么会再去额外加一些debug log来把相关变量的值输出。调试完毕之后再把这些debug log去掉。其实没必要这么麻烦,Python库中提供了cgitb模块来帮助做这些事情,它能够输出异常上下文所有相关变量的信息,不必每次自己再去手动加debug log。

cgitb的使用简单的不能想象:

def func(a, b):

returna / b

if__name__ =='__main__':

importcgitb

cgitb.enable(format='text')

importsys

importtraceback

func(1,0)

你可能感兴趣的:(搞清楚 Python traceback)