在python,一般都是使用try···except来对异常进行捕获
python try: 1 / 0 except Exception as e: print(e) # division by zero然而仅仅只有这些也看不出什么东西来,我们需要知道在哪一行代码引发的异常。
大家在程序报错的时候,会经常看到报错信息如下
Traceback (most recent call last):这个Traceback是什么鬼?实际上,这是python关于程序报错的回溯信息,来自于一个叫做traceback object的对象,而这个traceback object对象是通过sys.exc_info()来获取的
可以看到,sys.exc_info()获取了当前处理的exception的相关信息,并返回一个元组。元组的第一个元素是异常的类型,第二个元素是异常的value值,第三个异常信息则是traceback object。print(e)打印的是异常的值。
有了traceback object我们则可以打印和格式化traceback的相关信息
接收一个tracebackobject
python import sys import traceback try: 1 / 0 except NameError as e: exc_type, exc_value, exc_tb = sys.exc_info() traceback.print_tb(exc_tb) """ File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 6, in <module> 1 / 0 """ # 如果我们不捕获异常看看输出啥? """ Traceback (most recent call last): File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 6, in <module> 1 / 0 ZeroDivisionError: division by zero """ # 可以看到最后一行的ZeroDivisionError则是异常类型,division by zero则是异常值。中间的则是我们的traceback object然而除了traceback object,print_tb还可以接收两个参数
limit
比如我们在调用C函数出现了异常,但我们是先调用A函数,在A函数里面调用B函数,在B函数里面调用C函数,limit参数则是限制stack trace的层级的,如果为None也就是不指定,那么会打印所有层级
python import sys import traceback def C(): 1 / 0 def B(): C() def A(): B() try: A() except Exception as e: exc_type, exc_value, exc_tb = sys.exc_info() traceback.print_tb(exc_tb) """ File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 16, in <module> A() File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 12, in A B() File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 9, in B C() File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 6, in C 1 / 0 """ traceback.print_tb(exc_tb, limit=2) """ File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 16, in <module> A() File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 12, in A B() """file
可以指定file,输出到某个文件里,默认是sys.stderr
与print_tb相比多了两个参数,需要传入exc_type,exc_value,exc_tb,也就是sys.exc_info返回的三个值。与print_tb相比,打印信息多了开头的Traceback (most recent call last):,以及最后一行的异常类型和value信息。还有一个不同是当异常为SyntaxError时,会有"^"来指示语法错误的位置
python import sys import traceback def C(): 1 / 0 def B(): C() def A(): B() try: A() except Exception as e: exc_type, exc_value, exc_tb = sys.exc_info() traceback.print_exception(exc_type, exc_value, exc_tb) """ Traceback (most recent call last): File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 16, in <module> A() File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 12, in A B() File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 9, in B C() File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 6, in C 1 / 0 ZeroDivisionError: division by zero """可以看到,打印的结果和报错的信息是一样的。
和print_exception类似,只不过不需要我们手动的传入sys.exc_info返回的三个值,而是会自动帮我们调用
python import sys import traceback def C(): 1 / 0 def B(): C() def A(): B() try: A() except Exception as e: traceback.print_exc() """ Traceback (most recent call last): File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 16, in <module> A() File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 12, in A B() File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 9, in B C() File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 6, in C 1 / 0 ZeroDivisionError: division by zero """和print_exc一样,只不过是以字符串的形式返回,需要我们自己手动打印
python import sys import traceback def C(): 1 / 0 def B(): C() def A(): B() try: A() except Exception as e: tb_info = traceback.format_exc() print(tb_info) """ Traceback (most recent call last): File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 16, in <module> A() File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 12, in A B() File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 9, in B C() File "C:/Users/EDZ/Desktop/satori/wtfpython/1.py", line 6, in C 1 / 0 ZeroDivisionError: division by zero """转载于:https://www.cnblogs.com/valorchang/p/11395543.html