16.5.4 底层异常API
处理异常报告的另一种方法是利用print_exc()。这种方法使用sys.exc_info()得到当前线程的异常信息,格式化这个结构,并把文本输出到一个文件句柄(默认为sys.stder)。
import traceback
import sys
from traceback_example import produce_exception
print('print_exc() with no exception:')
traceback.print_exc(file=sys.stdout)
print()
try:
produce_exception()
except Exception as err:
print('print_exc():')
traceback.print_exc(file=sys.stdout)
print()
print('print_exc(1):')
traceback.print_exc(limit=1,file=sys.stdout)
在这个例子中替换了sys.stdout文件句柄,使信息消息和traceback消息能正确混合。
print_exc()就是print_exception()的快捷方式,print_exception()需要显式参数。
import traceback
import sys
from traceback_example import produce_exception
try:
produce_exception()
except Exception as err:
print('print_exception():')
exc_type,exc_value,exc_tb = sys.exc_info()
traceback.print_exception(exc_type,exc_value,exc_tb)
print_exception()的参数由sys.exc_info()生成。
print_exception()使用format_exception()准备文本。
import traceback
import sys
from pprint import pprint
from traceback_example import produce_exception
try:
produce_exception()
except Exception as err:
print('format_exception():')
exc_type,exc_value,exc_tb = sys.exc_info()
pprint(
traceback.format_exception(exc_type,exc_value,exc_tb),
width=65,
)
fromat_exception()中使用同样的3个参数——异常类型、异常值和traceback。
要以另外某种方式处理traceback,如以不同的方式格式化,可以使用extract_tb()以一种可用的形式获取数据。
import traceback
import sys
import os
from traceback_example import produce_exception
template = '{filename:<23}:{linenum}:{funcname}:\n {source}'
try:
producec_exception()
except Exception as err:
print('format_exception():')
exc_type,exc_value,exc_tb = sys.exc_info()
for tb_info in traceback.extract_tb(exc_tb):
filename,linenum,funcname,source = tb_info
if funcname != '<module>':
funcname = funcname + '()'
print(template.format(
filename=os.path.basename(filename),
linenum=linenum,
source=source,
funcname=funcname)
)
返回值是由traceback表示的每一层栈元素的一个列表。每个元素是一个元组,包括4个部分:源文件名,文件中的行号,函数名,以及该行去除了所有空白符的源文件(如果可以得到源文本)。