【转载】python-reraise重新抛出自定义异常——如何使traceback选择性保留?

转载自:https://blog.csdn.net/nnnora/article/details/84137036

 

1. 自定义异常
 在python中,自定义一个异常类的方法如下:

新建一个python文件exception.py,以后可以将该工程内的所有自定义异常类都写到该文件下。代码如下:

"""
自定义异常类
"""
 
 
# 参数类型异常类
class ParameterTypeError(Exception):
    _error_code = -1
    _error_type = "TypeError"
 
    def __init__(self, error_msg=""):    #可以理解为java的构造函数
        super().__init__(self)  # 初始化父类
        self.error_msg = error_msg    #设置构造函数的工作
 
    def __str__(self):    #设置转化为string的格式
        return '错误类型:' + ParameterTypeError._error_type + ';错误提示:' + self.error_msg
 
 
if __name__ == '__main__':
    try:
        raise ParameterValueError('参数异常')
    except ParameterValueError as e:
        print(e)
2. 如何重新抛出自定义异常?
如下代码,inner()方法会raise一个ConnectionError,在outer()方法中捕获该异常,然后抛出自定义的异常

def outer():
    try:
        inner()
    except Connection as e:
        raise ParameterValueError
3.traceback异常栈
如2代码 ,在python2及java的逻辑中,traceback会丢失捕捉的connectionError的异常信息,只保留未捕捉的异常:

但在python3中,会默认附加上捕捉的上个异常的traceback信息,如图: 

要想忽略掉被捕捉的异常,需要在抛出最后一个异常使用:

raise ParameterValueError from None
4.Traceback常用方法
在except代码块中,使用以下方法,可以捕捉traceback相应信息:

1. 

print('发生错误的文件:', e.__traceback__.tb_frame.f_globals['__file__'])

print('错误所在的行号:', e.__traceback__.tb_lineno)

print('错误信息', e)

2.(需要import sys)

sys.exc_info() 会返回一个3值元表 (type, value, traceback) ,其中:

type 从获取到的异常中得到类型名称,它是BaseException 的子类;
value 是捕获到的异常实例;
traceback 是一个 traceback 对象。
3.(需要import traceback)

traceback.extract_tb(tb [,limit ] )返回一个堆栈中异常信息(FrameSummary对象)列表,每一个对象是一个四元组(文件名,行号,函数名称*,文本), limit为条数

示例代码:

if __name__ == '__main__':
    try:
        main()
    except ConnectionError as e:
        t, v, tb = sys.exc_info()
        print(traceback.extract_tb(tb, 2))
    raise ParameterValueError from None
输出:

 

[<FrameSummary file /Users/mengxiangfen/project/tutor-ybc-course-pypackage/ybc_history/ybc_history/ybc_history.py, line 97 in <module>>, 
<FrameSummary file /Users/mengxiangfen/project/tutor-ybc-course-pypackage/ybc_history/ybc_history/ybc_history.py, line 91 in main>]
通过FrameSummary.filename, FrameSummary.lineno, FrameSummary.name可以获取到文件名/行号 /函数名

5. 如何在Python2中保留之前的异常栈信息?
见https://mozillazg.com/2016/08/python-the-right-way-to-catch-exception-then-reraise-another-exception.html#hidpython-2
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章