2009-08-11 169 views
6

我嘗試自定義sys.excepthook的行爲,如the recipe所述。無法覆蓋sys.excepthook

在IPython中

:import pdb, sys, traceback 
:def info(type, value, tb): 
: traceback.print_exception(type, value, tb) 
: pdb.pm() 
:sys.excepthook = info 
:-- 
>>> x[10] = 5 
------------------------------------------------- 
Traceback (most recent call last): 
    File "<ipython console>", line 1, in <module> 
NameError: name 'x' is not defined 
>>> 

pdb.pm()不會被調用。看來sys.excepthook = info在我的python 2.5安裝中不起作用。

回答

11

ipython,你正在使用,而不是普通的Python交互式shell,它本身捕獲所有異常,並不使用sys.excepthook。將它作爲ipython -pdb運行,而不是僅僅ipython,它會在未捕獲的異常時自動調用pdb,就像您嘗試使用您的excepthook一樣。

+0

怎麼會有人去使用除與IPython的鉤子? – levesque 2010-11-20 20:39:21

+1

這是部分誤導。 ipython本身也會捕獲異常,但是它的方式是使用sys.excepthook,所以你不能說它不使用sys.excepthook。不過,ipython會從用戶中刪除重寫此鉤子的能力。 – snapshoe 2010-11-21 00:44:38

+0

@fugacity和Alex - 我如何在發生異常的範圍內啓動嵌入式shell?我剛纔在這裏打開了一個問題:http://stackoverflow.com/questions/15752437/opening-an-ipython-shell-on-any-uncatched-exception,發現這個線程似乎高度相關。也許你可能知道如何做到這一點。 – 2013-04-01 22:01:32

0

請參閱this SO question並確保您的sitecustomize.py中沒有內容阻止以交互模式進行調試。

8

五年後,你寫這個,IPython仍然這樣工作,所以我想一個解決方案可能會有用的人使用谷歌搜索這個。

每次執行一行代碼時,IPython都會替換sys.excepthook,因此重寫sys.excepthook無效。此外,IPython甚至不會調用sys.excepthook,它會捕獲所有異常並在事情發生之前自行處理它們。

要在IPython運行時覆蓋異常處理程序,可以在其shell的showtraceback方法上進行monkeypatch。例如,這裏就是我重寫給什麼看起來像一個普通的Python回溯(因爲我不喜歡如何詳細IPython中的是):

def showtraceback(self): 
    traceback_lines = traceback.format_exception(*sys.exc_info()) 
    del traceback_lines[1] 
    message = ''.join(traceback_lines) 
    sys.stderr.write(message) 

import sys 
import traceback 
import IPython 
IPython.core.interactiveshell.InteractiveShell.showtraceback = showtraceback 

這個工作在兩個正常的終端控制檯和Qt控制檯。

0

克里斯的回答擴大,您可以使用其他功能像一個裝飾你自己的功能添加到jupyters showbacktrace:

from IPython.core.interactiveshell import InteractiveShell 
from functools import wraps 
import traceback 
import sys 

def change_function(func): 
    @wraps(func) 
    def showtraceback(*args, **kwargs): 
     # extract exception type, value and traceback 
     etype, evalue, tb = sys.exc_info() 
     if issubclass(etype, Exception): 
      print('caught an exception') 
     else: 
      # otherwise run the original hook 
      value = func(*args, **kwargs) 
      return value 
    return showtraceback 

InteractiveShell.showtraceback = change_function(InteractiveShell.showtraceback) 

raise IOError