53.traceback报错处理

1.Traceback 报错处理:

"""
1、traceback.print_exc()
2、traceback.format_exc()
3、traceback.print_exception()
"""
"""
简单说下这三个方法是做什么用的:
1、print_exc():是对异常栈输出
2、format_exc():是把异常栈以字符串的形式返回,print(traceback.format_exc()) 就相当于traceback.print_exc()
3、print_exception():traceback.print_exc()实现方式就是traceback.print_exception(sys.exc_info()),可
"""
def func(a, b):
    return a / b


if __name__ == '__main__':
    import sys
    import time
    import traceback
    
    try:
        func(1, 0)
    except Exception as e:
        print('***', type(e), e, '***')
        time.sleep(2)

        print("***traceback.print_exc():*** ")
        time.sleep(1)
        print(traceback.print_exc())
        time.sleep(2)

        print("***traceback.format_exc():*** ")
        time.sleep(1)
        print(traceback.format_exc())
        time.sleep(2)

        print("***traceback.print_exception():*** ")
        time.sleep(1)
        traceback.print_exception(*sys.exc_info())
        print(traceback.print_exception(*sys.exc_info()))


输出:
*** <class 'ZeroDivisionError'> division by zero ***

***traceback.print_exc():*** 
Traceback (most recent call last):
  File "C:/Users/yzt/Desktop/work/InfosecTestPlatform/f_time.py", line 22, in <module>
    func(1, 0)
  File "C:/Users/yzt/Desktop/work/InfosecTestPlatform/f_time.py", line 13, in func
    return a / b
ZeroDivisionError: division by zero


***traceback.format_exc():*** 
Traceback (most recent call last):
  File "C:/Users/yzt/Desktop/work/InfosecTestPlatform/f_time.py", line 22, in <module>
    func(1, 0)
  File "C:/Users/yzt/Desktop/work/InfosecTestPlatform/f_time.py", line 13, in func
    return a / b
ZeroDivisionError: division by zero


***traceback.print_exception():*** 
Traceback (most recent call last):
  File "C:/Users/yzt/Desktop/work/InfosecTestPlatform/f_time.py", line 22, in <module>
    func(1, 0)
  File "C:/Users/yzt/Desktop/work/InfosecTestPlatform/f_time.py", line 13, in func
    return a / b
ZeroDivisionError: division by zero

总结:
    可以看到输出的结果差不多,但是traceback.print_exc()无返回值,traceback.format_exc()有返回值,traceback.print_exception()无返回值.所以日志一般使用traceback.format_exc(),直接将报错信息写入日志文件.

看到这里就可以了,下面的不是很重要,上面够用了.

2.Traceback 如何优雅的处理报错

1.使用原因

1.产生原因
通过示例,我们发现普通的打印异常只有很少量的信息(通常是异常的value值),这种情况下我们很难定位在哪块代码出的问题,以及如何出现这种异常。那么到底要如何打印更加详细的信息呢?下面我们就来一一介绍。
def fun1():
    raise Exception(" --- func1 exception -- ")


def main():
    try:
        fun1()
    except Exception as e:
        print(e)


if __name__ == '__main__':
    main()
    
    # 输出: --- func1 exception -- 

2.sys.exc_info和traceback object
import sys
def fun1():
    raise Exception(" --- func1 exception -- ")

def main():
    try:
        fun1()
    except Exception as e:
        exc_type, exc_value, exc_traceback_obj = sys.exc_info()
        print(exc_type)
        print(exc_value)
        print(exc_traceback_obj)
if __name__ == '__main__':
    main()
输出结果:
<class 'Exception'>
<traceback object at 0x0000029A9FE3BF08>
 --- func1 exception -- 
    
通过以上示例我们可以看出,sys.exc_info()获取了当前处理的exception的相关信息,并返回一个元组,元组的第一个数据是异常的类型(示例是NameError类型),第二个返回值是异常的value值,第三个就是我们要的traceback object.

有了traceback object我们就可以通过traceback module来打印和格式化traceback的相关信息,下面我们就来看下traceback module的相关函数。    

2.traceback模块

3.print_tb输出到屏幕: 
	Python的traceback module提供一整套接口用于提取,格式化和打印Python程序的stack traces信息,下面我们通过例子来详细了解下这些接口:
    import sys
import traceback

def fun1():
    raise Exception(" --- func1 exception -- ")

def main():
    try:
        fun1()
    except Exception as e:
        exc_type, exc_value, exc_traceback_obj = sys.exc_info()
        traceback.print_tb(exc_traceback_obj)

if __name__ == '__main__':
    main()

输出结果:
File
"C:/Users/yzt/Desktop/work/InfosecTestPlatform/f_time.py", line10, in main
fun1()
File
"C:/Users/yzt/Desktop/work/InfosecTestPlatform/f_time.py", line5, in fun1
raise Exception(" --- func1 exception -- ")

这里我们可以发现打印的异常信息更加详细了,下面我们了解下print_tb的详细信息:

traceback.print_tb(tb[, limit[, file]])
    tb: 这个就是traceback object, 是我们通过sys.exc_info获取到的
    limit: 这个是限制stack trace层级的,如果不设或者为None,就会打印所有层级的stack trace
    file: 这个是设置打印的输出流的,可以为文件,也可以是stdout之类的file-like object。如果不设或为None,则输出到sys.stderr。	
        
4.print_tb输入文件
import sys
import traceback
def fun1():
    raise Exception(" --- func1 exception -- ")
def main():
    try:
        fun1()
    except Exception as e:
        exc_type, exc_value, exc_traceback_obj = sys.exc_info()
        fp = open("a.txt", "a")
        traceback.print_tb(exc_traceback_obj, file=fp)  # file=fp可以将错误信息输入文件中
        traceback.print_tb(exc_traceback_obj, file=sys.stdout) # sys.stdout可以将信息输出到屏幕
        fp.close()
if __name__ == '__main__':
    main()
    
5.print_exception
import sys
import traceback
def fun1():
    raise Exception(" --- func1 exception -- ")
def main():
    try:
        fun1()
    except Exception as e:
        exc_type, exc_value, exc_traceback_obj = sys.exc_info()
        fp = open("a.txt", "a")
        traceback.print_exception(exc_type, exc_value, exc_traceback_obj, limit=2, file=sys.stdout)
        fp.close()
if __name__ == '__main__':
    main()

看下定义:
traceback.print_exception(etype, value, tb[, limit[, file]])
    跟print_tb相比多了两个参数etype和value,分别是exception type和exception value,加上tb(traceback object),正好是sys.exc_info()返回的三个值
    另外,与print_tb相比,打印信息多了开头的"Traceback (most...)"信息以及最后一行的异常类型和value信息
    还有一个不同是当异常为SyntaxError时,会有"^"来指示语法错误的位置
    
6.print_exc
print_exc是简化版的print_exception, 由于exception type, value和traceback object都可以通过sys.exc_info()获取,因此print_exc()就自动执行exc_info()来帮助获取这三个参数了,也因此这个函数是我们的程序中最常用的,因为它足够简单
import sys
import traceback
def fun1():
    raise Exception(" --- func1 exception -- ")
def main():
    try:
        fun1()
    except Exception as e:
        traceback.print_exc(limit=2, file=sys.stdout)
if __name__ == '__main__':
    main()
输出结果:
    Traceback (most recent call last):
      File "C:/Users/yzt/Desktop/work/InfosecTestPlatform/f_time.py", line 11, in main
        fun1()
      File "C:/Users/yzt/Desktop/work/InfosecTestPlatform/f_time.py", line 6, in fun1
        raise Exception(" --- func1 exception -- ")
    Exception:  --- func1 exception -- 

7.fromat_exc
import logging
import traceback
logger = logging.getLogger("traceback_test")
def fun1():
    raise Exception(" --- func1 exception -- ")
def main():
    try:
        fun1()
    except Exception as e:
        logger.error(traceback.format_exc(limit=1))

if __name__ == '__main__':
    main()

从这个例子可以看出有时候我们想得到的是一个字符串,比如我们想通过logger将异常记录在log里,这个时候就需要format_exc了,这个也是最常用的一个函数,它跟print_exc用法相同,只是不直接打印而是返回了字符串
原文地址:https://www.cnblogs.com/liuzhanghao/p/13031327.html