【轉載】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
 

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