无法覆盖sys.excepthook

时间:2009-08-11 16:58:23

标签: python debugging ipython pdb

我尝试按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安装中不起作用。

4 个答案:

答案 0 :(得分:13)

你写这篇文章五年后,IPython仍然以这种方式工作,所以我猜一个解决方案可能对谷歌搜索这个人有用。

每次执行一行代码时,IPython都会替换sys.excepthook,因此覆盖sys.excepthook无效。此外,IPython甚至不会调用sys.excepthook,它会捕获所有异常并在事情发生之前处理它们。

要在IPython运行时覆盖异常处理程序,您可以对其shell showtraceback方法进行monkeypatch。例如,这里是我如何覆盖以给出看起来像普通Python回溯的东西(因为我不喜欢详细的IPython&#39;)

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控制台。

答案 1 :(得分:12)

ipython,你使用的是代替普通的Python交互式shell,它本身捕获所有异常并且不使用sys.excepthook。将其作为ipython -pdb而不是ipython运行,它会在未捕获的异常时自动调用pdb,就像您尝试处理异常错误一样。

答案 2 :(得分:0)

请参阅this SO question并确保sitecustomize.py中没有任何内容阻止在交互模式下进行调试。

答案 3 :(得分:0)

扩展Chris的回答,你可以使用另一个像装饰器这样的函数来为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