python-reraise重新丟擲自定義異常——如何使traceback選擇性保留?
阿新 • • 發佈:2018-11-21
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中保留之前的異常棧資訊?