11

我尝试按照配方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

5 回答 5

22

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

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

要在 IPython 运行时覆盖异常处理程序,您可以对其 shell 的showtraceback方法进行猴子补丁。例如,这是我如何覆盖以提供看起来像普通 Python 回溯的方法(因为我不喜欢 IPython 的冗长程度):

def showtraceback(self, *args, **kwargs):
    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 控制台。

于 2015-02-27T05:49:38.313 回答
14

您使用的 ipython 代替了普通的 Python 交互式 shell,它自己捕获所有异常并且不使用 sys.excepthook。运行它ipython -pdb而不是 just ipython,它会在未捕获的异常时自动调用 pdb,就像您尝试使用 exceptionhook 一样。

于 2009-08-11T18:18:53.350 回答
1

扩展 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
于 2018-03-08T15:27:12.850 回答
1

sys.excepthook不会在 ipython 中工作。我认为挂钩异常的推荐方法是使用该set_custom_exc方法,如下所示:

from IPython import get_ipython
ip = get_ipython()


def exception_handler(self, etype, evalue, tb, tb_offset=None):
    print("##### Oh no!!! #####")  # your handling of exception here
    self.showtraceback((etype, evalue, tb), tb_offset=tb_offset)  # standard IPython's printout

    
ip.set_custom_exc((Exception,), exception_handler)  # register your handler
raise Exception("##### Bad things happened! #####")  # see it in action

有关更多详细信息,请参阅文档:https ://ipython.readthedocs.io/en/stable/api/generated/IPython.core.interactiveshell.html#IPython.core.interactiveshell.InteractiveShell.set_custom_exc

于 2021-12-21T09:54:27.157 回答
0

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

于 2009-08-11T17:33:45.923 回答