Python的traceback模組的基本用法(異常處理)
文章目錄
一.Traceback介紹
在日常開發中,我們會做一些基本的異常處理,但是有時候只能列印我們處理的結果或者將異常打印出來,不能直觀的知道在哪個檔案中的哪一行出錯。
def func(num1, num2):
try:
x = num1 * num2
y = num1 / num2
return x, y
except Exception as e:
print("錯誤資訊:", e)
func(1, 0)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
執行結果:
而使用Python中traceback模組來進行處理可以直觀異常資訊:
import traceback
def func(num1, num2):
try:
x = num1 * num2
y = num1 / num2
return x, y
except:
traceback.print_exc()
func(1, 0)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
執行結果:
此錯誤輸出包含診斷問題所需的所有資訊。錯誤輸出的最後一行一般會告訴你引發了什麼型別的異常,以及關於該異常的一些相關資訊。錯誤資訊的前幾行指出了引發異常的程式碼檔案以及行數。
Python官網中有關traceback介紹:
該模組提供了一個標準介面,用於提取,格式和列印Python程式的堆疊痕跡。 它完全模仿了Python直譯器在列印堆疊跟蹤時的行為。 當您想在程式控制下列印堆疊跡線時,這非常有用,例如在直譯器周圍的“包裝器”中。
Python中的traceback資訊均來源於一個叫做traceback object的物件,而這個traceback object通常是通過函式sys.exc_info()來獲取的。
import sys
def func1(num1, num2):
x = num1 * num2
y = num1 / num2
return x, y
def func2():
func1(1, 0)
if __name__ == '__main__':
try:
func2()
except Exception as e:
exc_type, exc_value, exc_traceback = sys.exc_info()
print("exc_type:",exc_type)
print("exc_value:",exc_value)
print("exc_traceback:",exc_traceback)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
執行結果:
由上可知,sys.exc_info()獲取了當前處理的exception的相關資訊,並返回一個元組,元組的第一個資料是異常的型別,第二個返回值是異常的value值,第三個就是我們要的traceback object.
二.Traceback中常用函式
1.traceback.print_tb
作用:如果limit為正,則列印以limit來自traceback 物件tb的堆疊跟蹤條目(從呼叫方的幀開始)。否則,列印最後一個abs(limit)條目。如果省略限制或無限制,則列印所有條目。如果檔案被省略或無檔案,則輸出到sys.stderr;否則,它應該是一個開啟的檔案或類似檔案的物件來接收輸出。
在3.5版更改:增加了負限制支援。
import sys
import traceback
def func1(num1, num2):
x = num1 * num2
y = num1 / num2
return x, y
def func2():
func1(1, 0)
if __name__ == '__main__':
try:
func2()
except Exception as e:
exc_type, exc_value, exc_traceback = sys.exc_info()
traceback.print_tb(exc_traceback)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
執行結果:
說明:traceback.print_tb(tb, limit=None, file=None)
1.tb: 這個就是traceback object, 是我們通過sys.exc_info獲取到的
2.limit: 這個是限制stack trace層級的,如果不設或者為None,就會列印所有層級的stack trace
3.file: 這個是設定列印的輸出流的,可以為檔案,也可以是stdout之類的file-like object。如果不設或為None,則輸出到sys.stderr。
2.traceback.print_exception
import sys
import traceback
def func1(num1, num2):
x = num1 * num2
y = num1 / num2
return x, y
def func2():
func1(1, 0)
if __name__ == '__main__':
try:
func2()
except Exception as e:
exc_type, exc_value, exc_traceback = sys.exc_info()
traceback.print_exception(exc_type, exc_value, exc_traceback, limit=None, file=sys.stdout)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
執行結果:
說明:traceback.print_exception(etype, value, tb, limit=None, file=None, chain=True)
1.前三個引數正好是sys.exc_info()返回的三個值
2.與print_tb相比,列印資訊多了開頭的"Traceback (most…)“資訊以及最後一行的異常型別和value資訊
3.還有一個不同是當異常為SyntaxError時,會有”^"來指示語法錯誤的位置
3.traceback.print_exc
作用:print_exc是簡化版的print_exception, 由於exception type, value和traceback object都可以通過sys.exc_info()獲取,因此print_exc()就自動執行exc_info()來幫助獲取這三個引數。
所以traceback.print_exc(limit=None, file=None, chain=True)可將異常直接打印出來,同時可以將異常資訊寫入到檔案中
import traceback
def func(num1, num2):
try:
x = num1 * num2
y = num1 / num2
return x, y
except:
traceback.print_exc(file=open('YFater.txt','w+'))
func(1, 0)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
執行結果:
或者建立記憶體檔案物件:
import traceback
import io
def func(num1, num2):
try:
x = num1 * num2
y = num1 / num2
return x, y
except:
fp = io.StringIO() # 建立記憶體檔案物件
traceback.print_exc(file=fp)
message = fp.getvalue()
print(message)
func(1, 0)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
執行結果:
4.traceback.format_exc
作用:traceback.format_exc(limit=None, chain=True)返回的是一個欄位串,效果與traceback.print_exc()一致,比如我們想通過logger將異常記錄在log裡,就可以使用format_exc
import traceback
def func(num1, num2):
try:
x = num1 * num2
y = num1 / num2
return x, y
except:
print(traceback.format_exc())
func(1, 0)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
執行結果: