Horin|贺勤
Email: horin153@msn.com
Blog: http://blog.csdn.net/horin153/
Python 的 traceback.py 模块在调试中非常有用;但其默认的输出方式是 sys.stderr,导致在 realse 版本中(屏蔽了标准输出)无法有效捕获程序异常。如果把 traceback 的输出定向到我们能控制的 buffer 中,比如字符串,我们就能把捕获到的异常信息进行希望的后期处理,比如记入日志文件中。
下面的代码段就实现了这个功能:
#--------------- code begin --------------
# -*- coding: utf-8 -*-
import traceback
_title_tag = "[Traceback]/n"
class CStringBuf:
def __init__(self, title_tag="[Traceback]/n"):
self._buf = title_tag
def write(self, _str):
self._buf += _str
def read(self):
return self._buf
def handle_traceback(ex, mode=0x2, limit=None, title_tag=None):
"""up to 'limit' stack trace entries to a string.
"""
# mode:bit_1:print_stack,bit_2:print_exc;0xf:print all.
# if title_tag is None, use _titlt_tag.
if title_tag is None:
title_tag = _title_tag
_file = CStringBuf(title_tag)
if mode & 0x1:
traceback.print_stack(None, limit, _file)
if mode & 0x2:
traceback.print_exc(limit, _file)
if __debug__:
print '!!!!! handle_traceback begin !!!!!'
print _file.read()
print '!!!!! handle_traceback end !!!!!'
raise Exception, ex
else:
return _file.read()
#---test---
def crash():
_i = 5/0
def test():
try:
crash()
except Exception, ex:
handle_traceback(ex)
if __name__=="__main__":
test()
#--------------- code end ----------------
测试结果如下:
##---output---
#!!!!! handle_traceback begin !!!!!
#[Traceback]
#Traceback (most recent call last):
# File "F:/python/str_traceback.py", line 44, in test
# crash()
# File "F:/python/str_traceback.py", line 40, in crash
# _i = 5/0
#ZeroDivisionError: integer division or modulo by zero
#
#!!!!! handle_traceback end !!!!!
实现原理是:用 CStringBuf 代替 traceback 中的 file,也就把捕获到的异常信息定向到了字符串中。
handle_traceback() 的参数如下:
-- ex: 捕获到的异常,以便在 debug 时重新抛出;
-- mode: 处理模式,第一位为1时打印当前调用栈,第二位为1时打印异常信息;
-- limit: 打印调用栈的最大层次数;
-- title_tag: 在异常信息前打印的标签字符串。
使用很简单,就像 test() 函数一样:try 捕获异常,再用 handle_traceback 处理。