1. 程式人生 > 其它 >Python的traceback模組的基本用法(異常處理)

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

執行結果: