2011-06-05 25 views
21

有時在我調試時會引發異常。如何在Python調試器中看到異常的細節?

例如,考慮下面的代碼:

def some_function(): # Pretend this function is in a library... 
    # ...and deep within the library is an exception: 
    raise Exception('An exception message with valuable information.') 

import pdb; pdb.set_trace() 
try: 
    some_function() # Pretend I am debugging from this point using pdb. 
except: 
    pass 

雖然從some_function()通話調試,如果我發出了一個next命令我會看到有關有人提出[一把抓住]除了以下細節:

Exception: Exceptio...ation.',) 

這裏是從終端直複製/粘貼我在工作:

> /tmp/test.py(7)<module>() 
-> some_function() # Pretend I am debugging from this point using pdb. 
(Pdb) next 
Exception: Exceptio...ation.',) 
> /tmp/test.py(7)<module>() 
-> some_function() # Pretend I am debugging from this point using pdb. 
(Pdb) 

查看整個異常消息將非常有用。我怎樣才能在pdb中做到這一點?

+0

您使用的是什麼版本的Python?我的礦井不會像那樣截斷。 – Keith 2011-06-05 08:46:53

+0

版本2.7.1。請注意,raise語句是完整打印的,所以乍一看你可能會打印整個異常,但是當實際的異常被pdb截取(我不知道這個術語)時,它會被截斷。 – Buttons840 2011-06-05 17:43:05

+0

嗯,我實際上編寫了我自己的Python調試器的變體,它不會這樣做,也意味着自動進入調試器(使用sys.excepthook)。如果你喜歡,你可以嘗試一下。它是[調試器](http://code.google.com/p/pycopia/source/browse/#svn%2Ftrunk%2Fdebugger)子包。 – Keith 2011-06-06 01:44:55

回答

19

pdb存儲異常類型和價值傾倒在你的代碼中的任何點的堆棧跟蹤。

import traceback; print "".join(traceback.format_exception_only(*__exception__)) 

例如:你可以用打印回溯外部分pdb

> /tmp/test.py(7)<module>() 
-> some_function() # Pretend I am debugging from this point using pdb. 
(Pdb) next 
Exception: Exceptio...ation.',) 
> /tmp/test.py(7)<module>() 
-> some_function() # Pretend I am debugging from this point using pdb. 
(Pdb) import traceback; print "".join(traceback.format_exception_only(*__exception__)) 
Exception: An exception message with valuable information. 

(Pdb) 

不幸的是,這並不包括回溯的休息,但所有這些信息是可以通過where無論如何,pdb的命令。如果你真的想完整回溯,你可以添加以下到您的~/.pdbrc文件或粘貼到你的終端:

!global __currentframe, __stack; from inspect import currentframe as __currentframe, stack as __stack 
!global __format_exception_only, __print_stack; from traceback import format_exception_only as __format_exception_only, print_stack as __print_stack 
!global __Pdb; from pdb import Pdb as __Pdb 

# find the last frame on the stack with an object named "pdb" or "self" that is a pdb.Pdb object 
# works for pdb called the usual way, or pdb.pm(), or pdb.set_trace() 
!global __pdb; __pdb = [__framerec[0].f_locals.get("pdb") or __framerec[0].f_locals.get("self") for __framerec in __stack() if (__framerec[0].f_locals.get("pdb") or __framerec[0].f_locals.get("self")).__class__ == __Pdb][-1] 

alias traceback __print_stack(__pdb.stack[-1][0]); print "".join(__format_exception_only(*__exception__)) 

然後,你可以使用新的traceback別名得到你想要的東西:

> /tmp/test.py(7)<module>() 
-> some_function() # Pretend I am debugging from this point using pdb. 
(Pdb) next 
Exception: Exceptio...ation.',) 
> /tmp/test.py(7)<module>() 
-> some_function() # Pretend I am debugging from this point using pdb. 
(Pdb) traceback 
    File "test.py", line 7, in <module> 
    some_function() # Pretend I am debugging from this point using pdb. 
    File "test.py", line 3, in some_function 
    raise Exception('An exception message with valuable information.') 
Exception: An exception message with valuable information. 

(Pdb) 

警告:所有這些都依賴於未公開的pdbbdb內部組件,並且可能會中斷。

+0

非常有用的黑客感謝您。令人失望的是,沒有正常的方法去做一些如此常見和有用的事情。這個黑客也適用於pdb ++,所以我通過'ipdb'切換到那個。 – DBedrenko 2015-11-04 11:42:50

6

python調試器不會「打破異常」 - 如果您習慣了這種功能,這可能會非常令人沮喪。因此,我採取了記錄痕跡並從那裏回來的政策。

import logging 
try: 
    raise Exception('An exception message with valuable information.') 
except: 
    logging.exception('Error in test code') 

如果你使用一個很好的IDE(如Eclipse與PyDev的),對於堆棧跟蹤日誌條目由成直接跳到在代碼中適當的位置上的超鏈接。

您可以通過在__exception__進口回溯

import traceback 
trace = traceback.format_exc() 
+2

最好使用'日誌記錄。記錄異常追蹤的異常('Informative message')'以及關於失敗操作的任何信息('信息性消息',可以有參數等)。您可以使用'logging.debug(...,exc_info = True)'在任何級別(例如DEBUG)登錄。 – 2011-06-05 08:36:41

+0

我沒有意識到這一點 - 感謝Vinay。如果您沒有問題,我會更新我的答案? – 2011-06-05 08:48:41

+0

我正在使用twisted.python.log。我可以使用日誌記錄,但我寧願不。此外,嘗試:提高;除了:...不在我的代碼中,但在某處扭曲,(至少我是這麼認爲的)。所以如果我要使用這樣的日誌記錄,我將不得不修改扭曲的代碼。 – Buttons840 2011-06-05 17:45:22