日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python traceback什么意思_浅谈Python traceback的优雅处理

發布時間:2024/9/30 python 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python traceback什么意思_浅谈Python traceback的优雅处理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

剛接觸Python的時候,簡單的異常處理已經可以幫助我們解決大多數問題,但是隨著逐漸地深入,我們會發現有很多情況下簡單的異常處理已經無法解決問題了,如下代碼,單純的打印異常所能提供的信息會非常有限。

def func1():

raise Exception("--func1 exception--")

def main():

try:

func1()

except Exception as e:

print e

if __name__ == '__main__':

main()

執行后輸出如下:

--func1 exception--

通過示例,我們發現普通的打印異常只有很少量的信息(通常是異常的value值),這種情況下我們很難定位在哪塊代碼出的問題,以及如何出現這種異常。那么到底要如何打印更加詳細的信息呢?下面我們就來一一介紹。

sys.exc_info和traceback object

Python程序的traceback信息均來源于一個叫做traceback object的對象,而這個traceback object通常是通過函數sys.exc_info()來獲取的,先來看一個例子:

import sys

def func1():

raise NameError("--func1 exception--")

def main():

try:

func1()

except Exception as e:

exc_type, exc_value, exc_traceback_obj = sys.exc_info()

print "exc_type: %s" % exc_type

print "exc_value: %s" % exc_value

print "exc_traceback_obj: %s" % exc_traceback_obj

if __name__ == '__main__':

main()

執行后輸出如下:

exc_type:

exc_value: --func1 exception--

exc_traceback_obj:

通過以上示例我們可以看出,sys.exc_info()獲取了當前處理的exception的相關信息,并返回一個元組,元組的第一個數據是異常的類型(示例是NameError類型),第二個返回值是異常的value值,第三個就是我們要的traceback object.

有了traceback object我們就可以通過traceback module來打印和格式化traceback的相關信息,下面我們就來看下traceback module的相關函數。

traceback module

Python的traceback module提供一整套接口用于提取,格式化和打印Python程序的stack traces信息,下面我們通過例子來詳細了解下這些接口:

print_tb

import sys

import traceback

def func1():

raise NameError("--func1 exception--")

def main():

try:

func1()

except Exception as e:

exc_type, exc_value, exc_traceback_obj = sys.exc_info()

traceback.print_tb(exc_traceback_obj)

if __name__ == '__main__':

main()

輸出:

File "", line 11, in main

func1()

File "", line 6, in func1

raise NameError("--func1 exception--")

這里我們可以發現打印的異常信息更加詳細了,下面我們了解下print_tb的詳細信息:

traceback.print_tb(tb[, limit[, file]])

tb: 這個就是traceback object, 是我們通過sys.exc_info獲取到的

limit: 這個是限制stack trace層級的,如果不設或者為None,就會打印所有層級的stack trace

file: 這個是設置打印的輸出流的,可以為文件,也可以是stdout之類的file-like object。如果不設或為None,則輸出到sys.stderr。

print_exception

import sys

import traceback

def func1():

raise NameError("--func1 exception--")

def func2():

func1()

def main():

try:

func2()

except Exception as e:

exc_type, exc_value, exc_traceback_obj = sys.exc_info()

traceback.print_exception(exc_type, exc_value, exc_traceback_obj, limit=2, file=sys.stdout)

if __name__ == '__main__':

main()

輸出:

Traceback (most recent call last):

File "", line 13, in main

func2()

File "", line 9, in func2

func1()

NameError: --func1 exception--

看下定義:

traceback.print_exception(etype, value, tb[, limit[, file]])

跟print_tb相比多了兩個參數etype和value,分別是exception type和exception value,加上tb(traceback object),正好是sys.exc_info()返回的三個值

另外,與print_tb相比,打印信息多了開頭的"Traceback (most...)"信息以及最后一行的異常類型和value信息

還有一個不同是當異常為SyntaxError時,會有"^"來指示語法錯誤的位置

print_exc

print_exc是簡化版的print_exception, 由于exception type, value和traceback object都可以通過sys.exc_info()獲取,因此print_exc()就自動執行exc_info()來幫助獲取這三個參數了,也因此這個函數是我們的程序中最常用的,因為它足夠簡單

import sys

import traceback

def func1():

raise NameError("--func1 exception--")

def func2():

func1()

def main():

try:

func2()

except Exception as e:

traceback.print_exc(limit=1, file=sys.stdout)

if __name__ == '__main__':

main()

輸出(由于limit=1,因此只有一個層級被打印出來):

Traceback (most recent call last):

File "", line 13, in main

func2()

NameError: --func1 exception--

定義如下:traceback.print_exc([limit[, file]])

只有兩個參數,夠簡單

format_exc

import logging

import sys

import traceback

logger = logging.getLogger("traceback_test")

def func1():

raise NameError("--func1 exception--")

def func2():

func1()

def main():

try:

func2()

except Exception as e:

logger.error(traceback.format_exc(limit=1, file=sys.stdout))

if __name__ == '__main__':

main()

從這個例子可以看出有時候我們想得到的是一個字符串,比如我們想通過logger將異常記錄在log里,這個時候就需要format_exc了,這個也是最常用的一個函數,它跟print_exc用法相同,只是不直接打印而是返回了字符串。

traceback module中還有一些其它的函數,但因為并不常用,就不在展開來講,感興趣的同學可以看下參考鏈接中的文檔。

獲取線程中的異常信息

通常情況下我們無法將多線程中的異常帶回主線程,所以也就無法打印線程中的異常,而通過上邊學到這些知識,我們可以對線程做如下修改,從而實現捕獲線程異常的目的。

以下示例來自weidong的博客文章,稍有修改(見參考鏈接)

import threading

import traceback

def my_func():

raise BaseException("thread exception")

class ExceptionThread(threading.Thread):

def __init__(self, group=None, target=None, name=None, args=(), kwargs=None, verbose=None):

"""

Redirect exceptions of thread to an exception handler.

"""

threading.Thread.__init__(self, group, target, name, args, kwargs, verbose)

if kwargs is None:

kwargs = {}

self._target = target

self._args = args

self._kwargs = kwargs

self._exc = None

def run(self):

try:

if self._target:

self._target()

except BaseException as e:

import sys

self._exc = sys.exc_info()

finally:

#Avoid a refcycle if the thread is running a function with

#an argument that has a member that points to the thread.

del self._target, self._args, self._kwargs

def join(self):

threading.Thread.join(self)

if self._exc:

msg = "Thread '%s' threw an exception: %s" % (self.getName(), self._exc[1])

new_exc = Exception(msg)

raise new_exc.__class__, new_exc, self._exc[2]

t = ExceptionThread(target=my_func, name='my_thread')

t.start()

try:

t.join()

except:

traceback.print_exc()

輸出如下:

Traceback (most recent call last):

File "/data/code/testcode/thread_exc.py", line 43, in

t.join()

File "/data/code/testcode/thread_exc.py", line 23, in run

self._target()

File "/data/code/testcode/thread_exc.py", line 5, in my_func

raise BaseException("thread exception")

Exception: Thread 'my_thread' threw an exception: thread exception

這樣我們就得到了線程中的異常信息。

參考鏈接

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的python traceback什么意思_浅谈Python traceback的优雅处理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。