亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Python > 正文

搞清楚 Python traceback

2020-01-04 17:37:26
字體:
來源:轉載
供稿:網友

關于Python異常處理方面的一些基礎知識。

1. Python中的異常棧跟蹤

之前在做Java的時候,異常對象默認就包含stacktrace相關的信息,通過異常對象的相關方法printStackTrace()和getStackTrace()等方法就可以取到異常棧信息,能打印到log輔助調試或者做一些別的事情。但是到了Python,在2.x中,異常對象可以是任何對象,經常看到很多代碼是直接raise一個字符串出來,因此就不能像Java那樣方便的獲取異常棧了,因為異常對象和異常棧是分開的。而多數Python語言的書籍上重點在于描述Python中如何構造異常對象和raise try except finally這些的使用,對調試程序起關鍵作用的stacktrace往往基本上不怎么涉及。

python中用于處理異常棧的模塊是traceback模塊,它提供了print_exception、format_exception等輸出異常棧等常用的工具函數。

 

?
1
2
3
4
5
6
7
8
9
10
def func(a, b):
    return / b
if __name__ == '__main__':
    import sys
    import traceback
    try:
        func(10)
    except Exception as e:
        print "print exc"
        traceback.print_exc(file=sys.stdout)

 

 

輸出結果:

 

 

?
1
2
3
4
5
6
print exc
Traceback (most recent call last):
  File "./teststacktrace.py", line 7, in <module>
    func(1, 0)
  File "./teststacktrace.py", line 2, in func
    return a / b

 

 

其實traceback.print_exc()函數只是traceback.print_exception()函數的一個簡寫形式,而它們獲取異常相關的數據都是通過sys.exc_info()函數得到的。

 

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
def func(a, b):
    return / b
if __name__ == '__main__':
    import sys
    import traceback
    try:
        func(10)
    except Exception as e:
        print "print_exception()"
        exc_type, exc_value, exc_tb = sys.exc_info()
        print 'the exc type is:', exc_type
        print 'the exc value is:', exc_value
        print 'the exc tb is:', exc_tb
        traceback.print_exception(exc_type, exc_value, exc_tb)

 

 

輸出結果:

 

 

?
1
2
3
4
5
6
7
8
9
10
print_exception()
the exc type is: <type 'exceptions.ZeroDivisionError'>
the exc value is: integer division or modulo by zero
the exc tb is: <traceback object at 0x104e7d4d0>
Traceback (most recent call last):
  File "./teststacktrace.py", line 7, in <module>
    func(1, 0)
  File "./teststacktrace.py", line 2, in func
    return a / b
ZeroDivisionError: integer division or modulo by zero

 

 

sys.exc_info()返回的值是一個元組,其中第一個元素,exc_type是異常的對象類型,exc_value是異常的值,exc_tb是一個traceback對象,對象中包含出錯的行數、位置等數據。然后通過print_exception函數對這些異常數據進行整理輸出。

 

traceback模塊提供了extract_tb函數來更加詳細的解釋traceback對象所包含的數據:

 

?
1
2
3
4
5
6
7
8
9
10
11
def func(a, b):
    return / b
if __name__ == '__main__':
    import sys
    import traceback
    try:
        func(10)
    except:
        _, _, exc_tb = sys.exc_info()
        for filename, linenum, funcname, source in traceback.extract_tb(exc_tb):
            print "%-23s:%s '%s' in %s()" % (filename, linenum, source, funcname)

 

 

輸出結果:

 

 

?
1
2
3
samchimac:tracebacktest samchi$ python ./teststacktrace.py
./teststacktrace.py    :7 'func(1, 0)' in <module>()
./teststacktrace.py    :2 'return a / b' in func()

 

 

2. 使用cgitb來簡化異常調試

如果平時開發喜歡基于log的方式來調試,那么可能經常去做這樣的事情,在log里面發現異常之后,因為信息不足,那么會再去額外加一些debug log來把相關變量的值輸出。調試完畢之后再把這些debug log去掉。其實沒必要這么麻煩,Python庫中提供了cgitb模塊來幫助做這些事情,它能夠輸出異常上下文所有相關變量的信息,不必每次自己再去手動加debug log。

cgitb的使用簡單的不能想象:

 

?
1
2
3
4
5
6
7
8
def func(a, b):
        return / b
if __name__ == '__main__':
        import cgitb
        cgitb.enable(format='text')
        import sys
        import traceback
        func(10)

 

 

運行之后就會得到詳細的數據:

 

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
A problem occurred in a Python script.  Here is the sequence of
function calls leading up to the error, in the order they occurred.
 
 /Users/samchi/Documents/workspace/tracebacktest/teststacktrace.py in <module>()
    4   import cgitb
    5   cgitb.enable(format='text')
    6   import sys
    7   import traceback
    8   func(1, 0)
func = <function func>
 
 /Users/samchi/Documents/workspace/tracebacktest/teststacktrace.py in func(a=1, b=0)
    2   return a / b
    if __name__ == '__main__':
    4   import cgitb
    5   cgitb.enable(format='text')
    6   import sys
a = 1
b = 0

 

 

完全不必再去log.debug("a=%d" % a)了,個人感覺cgitb在線上環境不適合使用,適合在開發的過程中進行調試,非常的方便。

 

也許你會問,cgitb為什么會這么屌?能獲取這么詳細的出錯信息?其實它的工作原理同它的使用方式一樣的簡單,它只是覆蓋了默認的sys.excepthook函數,sys.excepthook是一個默認的全局異常攔截器,可以嘗試去自行對它修改:

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
def func(a, b):
        return / b
def my_exception_handler(exc_type, exc_value, exc_tb):
        print "i caught the exception:", exc_type
        while exc_tb:
                print "the line no:", exc_tb.tb_lineno
                print "the frame locals:", exc_tb.tb_frame.f_locals
                exc_tb = exc_tb.tb_next
 
if __name__ == '__main__':
        import sys
        sys.excepthook = my_exception_handler
        import traceback
        func(10)

 

 

輸出結果:

 

 

?
1
2
3
4
5
i caught the exception: <type 'exceptions.ZeroDivisionError'>
the line no: 14
the frame locals: {'my_exception_handler': <function my_exception_handler at 0x100e04aa0>, '__builtins__': <module '__builtin__' (built-in)>, '__file__''./teststacktrace.py''traceback': <module 'traceback' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/traceback.pyc'>, '__package__'None'sys': <module 'sys' (built-in)>, 'func': <function func at 0x100e04320>, '__name__''__main__''__doc__'None}
the line no: 2
the frame locals: {'a'1'b'0}

 

 

看到沒有?沒有什么神奇的東西,只是從stack frame對象中獲取的相關變量的值。frame對象中還有很多神奇的屬性,就不一一探索了。

 

3. 使用logging模塊來記錄異常

在使用Java的時候,用log4j記錄異常很簡單,只要把Exception對象傳遞給log.error方法就可以了,但是在Python中就不行了,如果直接傳遞異常對象給log.error,那么只會在log里面出現一行異常對象的值。

在Python中正確的記錄Log方式應該是這樣的:

 

?
1
2
3
logging.exception(ex)
logging.error(ex, exc_info=1# 指名輸出棧蹤跡, logging.exception的內部也是包了一層此做法
logging.critical(ex, exc_info=1# 更加嚴重的錯誤級別
 

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩在线观看网站| 国产日韩欧美黄色| 国产成人在线亚洲欧美| 日韩视频在线免费观看| 曰本色欧美视频在线| 国产日韩在线亚洲字幕中文| 成人淫片在线看| 亚洲最新av在线| 欧美视频不卡中文| 欧美黑人国产人伦爽爽爽| 亚洲精品第一国产综合精品| 在线色欧美三级视频| 国内精品视频久久| 亚洲精品国精品久久99热一| 国产精品视频xxxx| 亚洲v日韩v综合v精品v| 精品一区精品二区| 精品久久久久久亚洲精品| 欧美久久精品一级黑人c片| 久久黄色av网站| 精品视频www| 国产成人精品免费视频| 亚洲网站视频福利| 欧美孕妇孕交黑巨大网站| 欧美日韩亚洲精品一区二区三区| 欧美日韩免费一区| 亚洲欧美精品一区二区| 清纯唯美亚洲激情| 日韩电影免费在线观看| 国产精品网红直播| 久久噜噜噜精品国产亚洲综合| 国产精品久久久久久av| 国产91在线高潮白浆在线观看| 国产精品白丝jk喷水视频一区| 亚洲国产91色在线| 亚洲精品久久久一区二区三区| 欧美精品激情视频| 日韩精品视频免费| 亚洲综合一区二区不卡| 久久久国产精品免费| 91欧美精品午夜性色福利在线| 久久躁狠狠躁夜夜爽| 亚洲精品欧美日韩专区| 2019日本中文字幕| 国产日韩中文字幕| 亚洲综合视频1区| 欧美激情视频一区二区三区不卡| 成人性生交大片免费观看嘿嘿视频| 富二代精品短视频| 日韩在线观看精品| 精品久久久久久久久中文字幕| 国产精品你懂得| 91在线国产电影| 日韩国产精品亚洲а∨天堂免| 久久久久www| 色狠狠av一区二区三区香蕉蜜桃| 亚洲aa中文字幕| 一本色道久久88精品综合| 亚洲乱亚洲乱妇无码| 精品国产一区二区三区四区在线观看| 欧美成人午夜激情视频| 亚洲激情国产精品| 日韩精品视频在线免费观看| 成人av在线天堂| 欧美肥臀大乳一区二区免费视频| 国产精品一区二区三区在线播放| 午夜精品久久久久久99热软件| 久久手机精品视频| 亚洲精品免费一区二区三区| 欧美精品激情blacked18| 欧美老肥婆性猛交视频| 中文字幕亚洲激情| 欧美激情区在线播放| 免费97视频在线精品国自产拍| 日韩暖暖在线视频| 成人观看高清在线观看免费| 欧美精品videosex极品1| 亚洲女人被黑人巨大进入al| 国语自产精品视频在线看抢先版图片| 国产欧美一区二区三区在线看| 精品亚洲精品福利线在观看| 最近2019中文字幕在线高清| 欧美成人黄色小视频| 久久久精品欧美| 日韩精品久久久久久福利| 91超碰中文字幕久久精品| 精品久久久久久久久久久久久久| 日韩精品在线观看视频| 欧美在线免费视频| 欧美激情xxxx性bbbb| 亚洲黄色www网站| 美女av一区二区三区| 中文日韩在线视频| 国产精品中文久久久久久久| 97在线看免费观看视频在线观看| 精品久久久久久久久中文字幕| 国产亚洲激情在线| 日韩在线不卡视频| 美女性感视频久久久| 欧美极品少妇xxxxⅹ免费视频| 国产精品日韩精品| 91亚洲一区精品| 欧美日韩性视频在线| 久久综合伊人77777蜜臀| 久久综合伊人77777尤物| 国产亚洲精品久久久| 国产亚洲精品美女| 最近免费中文字幕视频2019| 欧美视频在线看| 青青久久av北条麻妃黑人| 中文字幕亚洲欧美日韩高清| 欧美在线视频一区| 国产日韩在线一区| 精品久久香蕉国产线看观看亚洲| 91sa在线看| 亚洲欧美另类人妖| 欧美性videos高清精品| 精品国内自产拍在线观看| 国产精品成人aaaaa网站| 精品福利在线观看| 亚洲国内高清视频| 欧美成年人视频网站欧美| 2019中文在线观看| 77777亚洲午夜久久多人| 91精品啪在线观看麻豆免费| 久久男人资源视频| 国产欧美日韩免费看aⅴ视频| 亚洲人成网站777色婷婷| 91色视频在线观看| 欧美电影免费观看电视剧大全| 日韩av手机在线| 国产精品69久久| 国产丝袜高跟一区| 日韩电影大全免费观看2023年上| 精品成人69xx.xyz| 欧洲日韩成人av| 欧美电影免费观看电视剧大全| 亚洲精品短视频| 免费成人高清视频| 亚洲第一视频网| 亚洲已满18点击进入在线看片| 成人a级免费视频| 伊人亚洲福利一区二区三区| 亚洲精品大尺度| 国产精品日日摸夜夜添夜夜av| 中文字幕成人在线| 国产精品久久久久久久7电影| 国产成人精品亚洲精品| 欧美日韩国产综合新一区| 91精品在线观看视频| 日韩综合中文字幕| 国产精品久久久久久搜索| 热久久这里只有精品| 欧美性猛交xxxx免费看| 成人黄色免费片| 亚洲韩国欧洲国产日产av| 国产精品自拍小视频| 91夜夜未满十八勿入爽爽影院| 日韩成人在线电影网| 国产精品爽黄69天堂a| 日韩av片永久免费网站| 日韩成人在线视频观看| 日韩国产高清视频在线| 亚洲福利影片在线|