2017-02-19 113 views
2

回溯模塊非常適合捕獲和處理異常,但在下面的示例中,它似乎從最近的異常中捕獲不完整的堆棧。traceback.print_exc()顯示不完整的堆棧跟蹤

考慮兩個文件,一個說 「mymod.py」:

import sys, traceback 

def func(): 
    try: 
     otherfunc() 
    except: 
     raise 
     #traceback.print_exc() 

def otherfunc(): 
    raise Exception('fake') 

而另外一個說: 「myfile.py」:

from mymod import * 
func() 

運行myfile.py給出:

Traceback (most recent call last): 
    File "myfile.py", line 2, in <module> 
    func() 
    File "/Users/rrdrake/temp/mymod.py", line 5, in func 
    otherfunc() 
    File "/Users/rrdrake/temp/mymod.py", line 11, in otherfunc 
    raise Exception('fake') 

現在更改mymod.py以註釋「raise」並取消註釋print_exc行。然後我們得到

Traceback (most recent call last): 
    File "/Users/rrdrake/temp/mymod.py", line 5, in func 
    otherfunc() 
    File "/Users/rrdrake/temp/mymod.py", line 11, in otherfunc 
    raise Exception('fake') 
Exception: fake 

請注意print_exc()在重新提升時不包括myfile.py框架。我如何使print_exc()包含原始調用框架?

請注意,如果我在except塊中添加traceback.print_stack(),它確實包含myfile.py框架,因此信息似乎可用。

回答

2

在您的第一個案例中,raise調用的例外情況在腳本的頂層出現。 Python調用sys.excepthook(),它顯示完整的回溯。

在第二種情況下,將捕獲異常並使用print_exc()來打印異常,並停止在調用函數處(您的案例爲otherfunc()),因此不會獲得完整的回溯。

你可以改變,通過使用自己的回溯/異常打印功能, 類似的規定:

def print_full_stack(tb=None): 
    if tb is None: 
     tb = sys.exc_info()[2] 

    print 'Traceback (most recent call last):' 
    for item in reversed(inspect.getouterframes(tb.tb_frame)[1:]): 
     print ' File "{1}", line {2}, in {3}\n'.format(*item), 
     for line in item[4]: 
      print ' ' + line.lstrip(), 
     for item in inspect.getinnerframes(tb): 
      print ' File "{1}", line {2}, in {3}\n'.format(*item), 
     for line in item[4]: 
      print ' ' + line.lstrip(), 

只是print_full_stack()取代traceback.print_exc()。該功能涉及inspect模塊以獲取代碼幀。

你可以閱讀這個博客的更多信息:http://blog.dscpl.com.au/2015/03/generating-full-stack-traces-for.html