最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談Python traceback的優(yōu)雅處理

 更新時間:2018年08月31日 10:51:41   作者:sunsky303  
這篇文章主要介紹了淺談Python traceback的優(yōu)雅處理,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

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

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


def main():
  try:
    func1()
  except Exception as e:
    print e


if __name__ == '__main__':
  main()

執(zhí)行后輸出如下:

--func1 exception--

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

sys.exc_info和traceback object

Python程序的traceback信息均來源于一個叫做traceback object的對象,而這個traceback object通常是通過函數(shù)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()

執(zhí)行后輸出如下:

exc_type: <type 'exceptions.NameError'>
exc_value: --func1 exception--
exc_traceback_obj: <traceback object at 0x7faddf5d93b0>

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

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

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 "<ipython-input-23-52bdf2c9489c>", line 11, in main
    func1()
File "<ipython-input-23-52bdf2c9489c>", line 6, in func1
    raise NameError("--func1 exception--")

這里我們可以發(fā)現(xiàn)打印的異常信息更加詳細了,下面我們了解下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 "<ipython-input-24-a68061acf52f>", line 13, in main
    func2()
  File "<ipython-input-24-a68061acf52f>", line 9, in func2
    func1()
NameError: --func1 exception--

看下定義:

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

  1. 跟print_tb相比多了兩個參數(shù)etype和value,分別是exception type和exception value,加上tb(traceback object),正好是sys.exc_info()返回的三個值
  2. 另外,與print_tb相比,打印信息多了開頭的"Traceback (most...)"信息以及最后一行的異常類型和value信息
  3. 還有一個不同是當異常為SyntaxError時,會有"^"來指示語法錯誤的位置

print_exc

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

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 "<ipython-input-25-a1f5c73b97c4>", line 13, in main
    func2()
NameError: --func1 exception--

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

只有兩個參數(shù),夠簡單

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了,這個也是最常用的一個函數(shù),它跟print_exc用法相同,只是不直接打印而是返回了字符串。

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

獲取線程中的異常信息

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

以下示例來自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 <module>
    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

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

參考鏈接

traceback官方文檔 https://docs.python.org/2/library/traceback.html

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

相關文章

  • Python語言基礎之函數(shù)語法

    Python語言基礎之函數(shù)語法

    這篇文章主要介紹了Python語言基礎中的函數(shù)語法,文中有詳細的代碼示例供大家參考,對學習或工作有一定的幫助,需要的朋友可以參考閱讀下
    2023-05-05
  • python繪制帶有誤差棒條形圖的實現(xiàn)

    python繪制帶有誤差棒條形圖的實現(xiàn)

    本文主要介紹了python繪制帶有誤差棒條形圖的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-07-07
  • Python自定義聚合函數(shù)merge與transform區(qū)別詳解

    Python自定義聚合函數(shù)merge與transform區(qū)別詳解

    這篇文章主要介紹了Python自定義聚合函數(shù)merge與transform區(qū)別詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-05-05
  • Restful_framework視圖組件代碼實例解析

    Restful_framework視圖組件代碼實例解析

    這篇文章主要介紹了Restful_framework視圖組件代碼實例解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-11-11
  • python實現(xiàn)高斯投影正反算方式

    python實現(xiàn)高斯投影正反算方式

    今天小編就為大家分享一篇python實現(xiàn)高斯投影正反算方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-01-01
  • 關于Python中函數(shù)的幾種形參

    關于Python中函數(shù)的幾種形參

    這篇文章主要介紹了關于Python中函數(shù)的幾種形參,python中函數(shù)是非常重要的一個知識點,想要把函數(shù)學習好,就必須要把函數(shù)的參數(shù)學習好,這樣才能夠進行很好的傳遞參數(shù),發(fā)揮出應有的作用,需要的朋友可以參考下
    2023-08-08
  • python將unicode和str互相轉化的實現(xiàn)

    python將unicode和str互相轉化的實現(xiàn)

    這篇文章主要介紹了python將unicode和str互相轉化的實現(xiàn),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-05-05
  • 對python pandas中 inplace 參數(shù)的理解

    對python pandas中 inplace 參數(shù)的理解

    這篇文章主要介紹了對python pandas中 inplace 參數(shù)的理解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-06-06
  • 用python批量生成文件夾的實現(xiàn)方法舉例

    用python批量生成文件夾的實現(xiàn)方法舉例

    這篇文章主要介紹了使用Python腳本批量生成文件夾的方法,可以用于創(chuàng)建順序文件夾或嵌套文件夾,通過設置路徑和循環(huán),可以自動命名并創(chuàng)建文件夾,提高工作效率,需要的朋友可以參考下
    2025-03-03
  • Python底層封裝實現(xiàn)方法詳解

    Python底層封裝實現(xiàn)方法詳解

    這篇文章主要介紹了Python底層封裝實現(xiàn)方法詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-01-01

最新評論

天镇县| 罗江县| 德惠市| 奉化市| 都匀市| 海阳市| 永平县| 鄂托克前旗| 仪陇县| 武清区| 永春县| 嘉鱼县| 筠连县| 贵阳市| 精河县| 伊吾县| 二手房| 阜新| 白水县| 乌鲁木齐县| 浦江县| 潍坊市| 阿图什市| 福清市| 宁德市| 大洼县| 柯坪县| 文安县| 临桂县| 晋江市| 云阳县| 嘉兴市| 泸水县| 东乡族自治县| 娄烦县| 瑞安市| 汝南县| 会理县| 抚州市| 乐平市| 江都市|