除了使用 sys.exc_info() 方法獲取更多的異常資訊之外,還可以使用 traceback 模組,該模組可以用來檢視異常的傳播軌跡,追蹤異常觸發的源頭。
下面示例顯示了如何顯示異常傳播軌跡:
class selfexception(exception):pass
def main():
firstmethod()
def firstmethod():
secondmethod()
def secondmethod():
thirdmethod()
def thirdmethod():
raise selfexception("自定義異常資訊")
main()
上面程式中 main() 函式呼叫 firstmethod(),firstmethod() 呼叫 secondmethod(),secondmethod() 呼叫 thirdmethod(),thirdmethod() 直接引發乙個 selfexception 異常。執行上面程式,將會看到如下所示的結果:
traceback (most recent call last):
file "c:\users\mengma\desktop\1.py", line 11, in
main()
file "c:\users\mengma\desktop\1.py", line 4, in main <--mian函式
firstmethod()
file "c:\users\mengma\desktop\1.py", line 6, in firstmethod <--第三個
secondmethod()
file "c:\users\mengma\desktop\1.py", line 8, in secondmethod <--第二個
thirdmethod()
file "c:\users\mengma\desktop\1.py", line 10, in thirdmethod <--異常源頭
raise selfexception("自定義異常資訊")
selfexception: 自定義異常資訊
從輸出結果可以看出,異常從 thirdmethod() 函式開始觸發,傳到 secondmethod() 函式,再傳到 firstmethod() 函式,最後傳到 main() 函式,在 main() 函式止,這個過程就是整個異常的傳播軌跡。
在實際應用程式的開發中,大多數複雜操作都會被分解成一系列函式或方法呼叫。這是因為,為了具有更好的可重用性,會將每個可重用的**單元定義成函式或方法,將複雜任務逐漸分解為更易管理的小型子任務。由於乙個大的業務功能需要由多個函式或方法來共同實現,在最終程式設計模型中,很多物件將通過一系列函式或方法呼叫來實現通訊,執行任務。
所以,當應用程式執行時,經常會發生一系列函式或方法呼叫,從而形成「函式呼叫戰」。異常的傳播則相反,只要異常沒有被完全捕獲(包括異常沒有**獲,或者異常被處理後重新引發了新異常),異常就從發生異常的函式或方法逐漸向外傳播,首先傳給該函式或方法的呼叫者,該函式或方法的呼叫者再傳給其呼叫者,直至最後傳到 python 直譯器,此時 python 直譯器會中止該程式,並列印異常的傳播軌跡資訊。
很多初學者一看到輸出結果所示的異常提示資訊,就會驚慌失措,他們以為程式出現了很多嚴重的錯誤,其實只有乙個錯誤,系統提示那麼多行資訊,只不過是顯示異常依次觸發的軌跡。
其實,上面程式的運算結果顯示的異常傳播軌跡資訊非常清晰,它記錄了應用程式中執行停止的各個點。最後一行資訊詳細顯示了異常的型別和異常的詳細訊息。從這一行向上,逐個記錄了異常發生源頭、異常依次傳播所經過的軌跡,並標明異常發生在哪個檔案、哪一行、哪個函式處。
使用 traceback 模組檢視異常傳播軌跡,首先需要將 traceback 模組引入,該模組提供了如下兩個常用方法:
可能有讀者好奇,從上面方法看不出它們到底處理哪個異常的傳播軌跡資訊。實際上我們常用的 print_exc() 是 print_exc([limit[, file]]) 省略了 limit、file 兩個引數的形式。而 print_exc([limit[, file]]) 的完整形式是print_exception(etype, value, tb[,limit[, file]])
,在完整形式中,前面三個引數用於分別指定異常的如下資訊:
當程式處於 except 塊中時,該 except 塊所捕獲的異常資訊可通過 sys 物件來獲取,其中 sys.exc_type、sys.exc_value、sys.exc_traceback 就代表當前 except 塊內的異常型別、異常值和異常傳播軌跡。
簡單來說, print_exc([limit[, file]]) 相當於如下形式:
print_exception(sys.exc_etype, sys.exc_value, sys.exc_tb[, limit[, file]])
也就是說,使用 print_exc([limit[, file]]) 會自動處理當前 except 塊所捕獲的異常。該方法還涉及兩個引數:
limit:用於限制顯示異常傳播的層數,比如函式 a 呼叫函式 b,函式 b 發生了異常,如果指定 limit=1,則只顯示函式 a 裡面發生的異常。如果不設定 limit 引數,則預設全部顯示。
file:指定將異常傳播軌跡資訊輸出到指定檔案中。如果不指定該引數,則預設輸出到控制台。
借助於 traceback 模組的幫助,我們可以使用 except 塊捕獲異常,並在其中列印異常傳播資訊,包括把它輸出到檔案中。例如如下程式:
# 匯入trackback模組import traceback
class selfexception(exception): pass
def main():
firstmethod()
def firstmethod():
secondmethod()
def secondmethod():
thirdmethod()
def thirdmethod():
raise selfexception("自定義異常資訊")
try:
main()
except:
# 捕捉異常,並將異常傳播資訊輸出控制台
traceback.print_exc()
# 捕捉異常,並將異常傳播資訊輸出指定檔案中
traceback.print_exc(file=open('log.txt', 'a'))
上面程式第一行先導入了 traceback 模組,接下來程式使用 except 捕獲程式的異常,並使用 traceback 的 print_exc() 方法輸出異常傳播資訊,分別將它輸出到控制台和指定檔案中。
執行上面程式,同樣可以看到在控制台輸出異常傳播資訊,而且在程式目錄下生成了乙個 log.txt 檔案,該檔案中同樣記錄了異常傳播資訊。
traceback模組 獲取詳細的異常資訊
try 1 0except exception,e print e 輸出結果是integer division or modulo by zero,只知道是報了這個錯,但是卻不知道在哪個檔案哪個函式哪一行報的錯。下面使用traceback模組 import traceback try 1 0exce...
traceback 異常跟蹤
traceback 用來跟蹤異常返回資訊。異常物件預設包含stacktrace相關的資訊,通過異常物件的相關方法printstacktrace 和getstacktrace 等方法就可以取到異常棧資訊,能列印log輔助除錯。1 author zechary 2 3import traceback 4...
使用traceback獲取詳細的異常資訊
try 1 0except exception,e print e輸出結果是integer division or modulo by zero,只知道是報了這個錯,但是卻不知道在哪個檔案哪個函式哪一行報的錯。下面使用traceback模組 import traceback try 1 0excep...