為了在python GUI 程式開發時有更好的開發者體驗, 筆者喜歡先收集別人的痛點及各種解決方案, 整理成屬於自己的優化方案再導入到GUI專案中, 而Exception 的呈現方式就是其中一個痛點.
引用自近期網友詢問Python 的Try Exception的問題片段 ...
引用來源: https://reurl.cc/XlWje3
在專案中有很多使用者會使用exception 去做例外的攔截, 但很常遇到的狀況是Exception並不會把完整的CallStack及位置顯示出來, 這就增添除錯時的困難度, 尤其在大型專案或多檔案的程式碼中, 不處理好就會演變成一場大災難.
來看個簡單的例子:
dict_a = {0:'hello',1:'hi'}
def run():
    try:
       print ("Hello, this is dmeo.\n")
       print(dict_a[2])
       print ("End")
    except Exception as err:
        print(err)
run()
例外發生的時候看不到完整的callstack 及行號
這次筆者使用traceback , 這個內建的模組做實驗
import sys
import traceback
 
dict_a = {0:'hello', 1:'hi'}
def run():
   try:
       print ("Hello, this is demo.\n")
       print (dict_a[2])
       print ("End")
   except Exception as err:
       err_type = err.__class__.__name__ # 取得錯誤的class 名稱
       info = err.args[0] # 取得詳細內容
       detains = traceback.format_exc() # 取得完整的tracestack
       n1, n2, n3 = sys.exc_info() #取得Call Stack
       lastCallStack =  traceback.extract_tb(n3)[-1] # 取得Call Stack 最近一筆的內容
       fn = lastCallStack [0] # 取得發生事件的檔名
       lineNum = lastCallStack[1] # 取得發生事件的行數
       funcName = lastCallStack[2] # 取得發生事件的函數名稱
       errMesg = f"FileName: {fn}, lineNum: {lineNum}, Fun: {funcName}, reason: {info}, trace:\n {traceback.format_exc()}"
       print(errMesg)
       
run()
流程
執行結果
結論
我們可以把這個好用的模組使用方式包成一個簡單的模組, 搭配logging或寫成檔案去做相關的紀錄, 這樣就可以減少程式出錯後的除錯難度
參考資料