简单描述
日常开发中,我们为了保证程序的可持续运行,通常会使用try — except进行异常捕获,如下所示:
def insert_data(self, con, cursor, sql_insert, data):
try:
cursor.executemany(sql_insert, tuple(data))
con.commit()
print("入库成功")
except Exception as e:
con.rollback()
print(f"出错了: {e}")
finally:
print("关闭连接")
self.close_mysql(con, cursor)
def close_mysql(self, con, cursor):
cursor.close()
con.close()
这种情况下一般只能得知错误的信息,即 except Exception as e中的变量e,但是项目程序实际运行时,无法得知更加具体的错误信息,如下所示:
出错了: not enough arguments for format string
出错了: not enough arguments for format string
出错了: not enough arguments for format string
出错了: not enough arguments for format string
出错了: not enough arguments for format string
出错了: not enough arguments for format string
出错了: not enough arguments for format string
出错了: not enough arguments for format string
关闭连接
这样在程序调试维护的时候,很难定位到具体错误的函数体和错误的语句。但是,通过traceback模块可以很好的解决这个问题。
traceback介绍
sys.exc_info和traceback object
python程序运行报错的信息,都是由一个叫traceback object的对象提供的,这个对象是可以通过sys.exc_info()获取的,如下:
str_test = "0123456"
try:
str_test[:3] = "9"
except:
exc_type, exc_value, exc_traceback_obj = sys.exc_info()
print(f"exc_type: {exc_type}")
print(f"exc_value: {exc_value}")
print(f"exc_traceback_obj: {exc_traceback_obj}")
输出如下:
exc_type: <class 'TypeError'>
exc_value: 'str' object does not support item assignment
exc_traceback_obj: <traceback object at 0x000001DAC2BFDC88>
从上面这个例子可以看出,sys.exc_info()获取了当前程序运行出错的相关信息,其有3个返回值,第一个是异常的类型(示例为:TypeError),第二个是异常的信息,第三个其实就是traceback object这个对象。
traceback模块介绍
traceback模块是python的一个内置模块,可以用来查看程序的运行报错等信息。其主要常用的有4个函数,分别如下:
-
print_tb
-
print_exception
-
print_exc
-
format_exc
print_tb示例如下:
import sys
import traceback
str_test = "0123456"
try:
str_test[:3] = "9"
except:
exc_type, exc_value, exc_traceback_obj = sys.exc_info()
# print(f"exc_type: {exc_type}")
# print(f"exc_value: {exc_value}")
# print(f"exc_traceback_obj: {exc_traceback_obj}")
traceback.print_tb(exc_traceback_obj)
输出如下:
File "E:/PycharmProjects/Tesome动态可配置数据解析/Tools/logger_tools.py", line 10, in <module>
str_test[:3] = "9"
这里我们发现打印的信息更加详细了,指出了报错的代码行数,下面我们来了解下print_tb这个函数:
traceback.print_tb(tb[, limit[, file]])
- tb: 就是traceback object, 是我们通过sys.exc_info获取到的
- limit: 这个是限制报错出现的层级的,如果不设或者为None,就会打印所有层级的报错信息
- file: 这个是设置打印的输出流的,可以为文件,也可以是stdout之类的file-like object。如果不设或为None,则输出到sys.stderr。
print_exception示例如下:
import sys
import traceback
str_test = "0123456"
try:
str_test[:3] = "9"
except:
exc_type, exc_value, exc_traceback_obj = sys.exc_info()
# print(f"exc_type: {exc_type}")
# print(f"exc_value: {exc_value}")
# print(f"exc_traceback_obj: {exc_traceback_obj}")
# traceback.print_tb(exc_traceback_obj)
traceback.print_exception(exc_type, exc_value, exc_traceback_obj)
输出如下内容:
Traceback (most recent call last):
File "E:/PycharmProjects/Tesome动态可配置数据解析/Tools/logger_tools.py", line 10, in <module>
str_test[:3] = "9"
TypeError: 'str' object does not support item assignment
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时,会有"^"来指示语法错误的位置
print_exc示例如下:
import traceback
str_test = "0123456"
try:
str_test[:3] = "9"
except:
# exc_type, exc_value, exc_traceback_obj = sys.exc_info()
# print(f"exc_type: {exc_type}")
# print(f"exc_value: {exc_value}")
# print(f"exc_traceback_obj: {exc_traceback_obj}")
# traceback.print_tb(exc_traceback_obj)
traceback.print_exc()
输出内容和print_exception相同,因为print_exc是简化版的print_exception,可从源码中明白:
def print_exc(limit=None, file=None, chain=True):
"""Shorthand for 'print_exception(*sys.exc_info(), limit, file)'."""
print_exception(*sys.exc_info(), limit=limit, file=file, chain=chain)
format_exc:
其就是将print_exc的内容转为字符串,可以存入一个变量中
import traceback
str_test = "0123456"
try:
str_test[:3] = "9"
except:
# exc_type, exc_value, exc_traceback_obj = sys.exc_info()
# print(f"exc_type: {exc_type}")
# print(f"exc_value: {exc_value}")
# print(f"exc_traceback_obj: {exc_traceback_obj}")
# traceback.print_tb(exc_traceback_obj)
message = traceback.format_exc()
print(message)
输出如下:
format_exc的好处就是当我们想要将错误信息写入日志的时候,就可以使用这个字符串的变量了。
以上内容辅助参考了简书上的一位朋友的博客,感谢这位朋友的 分享。