简体   繁体   English

不能覆盖 sys.excepthook

[英]cannot override sys.excepthook

I try to customize behavior of sys.excepthook as described by the recipe .我尝试按照配方中的描述自定义sys.excepthook行为。

in ipython:在 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() is not being called. pdb.pm()没有被调用。 It seems that sys.excepthook = info doesn't work in my python 2.5 installation.似乎sys.excepthook = info在我的 python 2.5 安装中不起作用。

Five years after you wrote this, IPython still works this way, so I guess a solution might be useful to people googling this. 在你写这篇文章五年后,IPython仍然以这种方式工作,所以我猜一个解决方案可能对谷歌搜索这个有用。

IPython replaces sys.excepthook every time you execute a line of code, so your overriding of sys.excepthook has no effect. 每次执行一行代码时,IPython都会替换sys.excepthook ,因此覆盖sys.excepthook无效。 Furthermore, IPython doesn't even call sys.excepthook , it catches all exceptions and handles them itself before things get that far. 此外,IPython甚至不调用sys.excepthook ,它捕获所有异常并在事情发生之前处理它们。

To override the exception handler whilst IPython is running, you can monkeypatch over their shell's showtraceback method. 要在IPython运行时覆盖异常处理程序,您可以对其shell的showtraceback方法进行showtraceback For example, here's how I override to give what looks like an ordinary Python traceback (because I don't like how verbose IPython's are): 例如,这是我如何覆盖以给出看起来像普通的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

This works in both the normal terminal console and the Qt console. 这适用于普通终端控制台和Qt控制台。

ipython, which you're using instead of the normal Python interactive shell, traps all exceptions itself and does NOT use sys.excepthook. 你正在使用ipython而不是普通的Python交互式shell,它会捕获所有异常,并且不使用sys.excepthook。 Run it as ipython -pdb instead of just ipython , and it will automatically invoke pdb upon uncaught exceptions, just as you are trying to do with your excepthook. 运行它作为ipython -pdb而不仅仅是ipython ,它会在未捕获的异常时自动调用pdb,就像你试图用你的excepthook一样。

expanding on Chris answer, you can use another function like a decorator to add your own functionality to jupyters showbacktrace: 扩展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

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

sys.excepthook won't work in ipython. sys.excepthook在 ipython 中不起作用。 I think the recommended way of hooking to exceptions is to use the set_custom_exc method, like this:我认为挂钩异常的推荐方法是使用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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM