抛出异常时是否可以自动进入调试器?

时间:2013-09-23 13:16:26

标签: python exception

如果在最初抛出函数之外捕获异常,则会失去对本地堆栈的访问权限。因此,无法检查可能导致异常的变量值。

有没有办法在每次抛出异常来检查本地堆栈时自动开始进入调试器(import pdb; pdb.set_trace())?

6 个答案:

答案 0 :(得分:16)

你不想打破每一个例外;惯用的Python代码大量使用异常(EAFP),因此您将不断破坏不相关的代码。

相反,请使用pdb post-mortem:import pdb; pdb.pm()。这使用sys.last_traceback来检查堆栈,包括抛出点的本地人。

答案 1 :(得分:12)

ipython支持此(http://ipython.org)。从ipython里面做,

%pdb on

从那时起,每当出现异常时,它都会自动将你放入调试器中。

请注意,您(可能)很快就会厌倦这种情况......每当您输入错误并出现语法错误时,您将不得不退出调试器。但它有时很有用。

答案 2 :(得分:4)

我在回答What is the simplest way of using Python pdb to inspect the cause of an unhandled exception?

时找到了我要找的东西
  

用它包裹:

<!-- language: lang-py -->
def debug_on(*exceptions):
    if not exceptions:
        exceptions = (AssertionError, )
    def decorator(f):
        @functools.wraps(f)
        def wrapper(*args, **kwargs):
            try:
                return f(*args, **kwargs)
            except exceptions:
                pdb.post_mortem(sys.exc_info()[2])
        return wrapper
    return decorator
     

示例:

@debug_on(TypeError)
def buggy_function()
    ....
    raise TypeError

答案 3 :(得分:0)

如果您只想包装一个函数的某些内部部分,或者需要装饰多个函数,则可以使用上下文管理器代替已接受的答案。我现在使用的是捕获所有异常的简单版本。我也建议使用pudb

from contextlib import contextmanager

@contextmanager
def postmortem_pudb():
    try:
        yield
    except Exception as exc:
        pudb.post_mortem()

像这样使用

with postmortem_pudb():
    function_that_might_throw_some()
    ...
    another_function_that_might_throw_some()
    ...
    yet_another_function_that_might_throw_some()

答案 4 :(得分:0)

我知道这很旧,并且已经接受了答案,但是我发现这很有用(对于IPython): 使用--pdb选项启动IPython

ipython --pdb <whatever command>

答案 5 :(得分:0)

对于python 3(今天为3.8),可以使用

python3 -m pdb myscript.py

来自docs

当作为脚本调用时,pdb将自动输入验尸 如果正在调试的程序异常退出,则进行调试。后 事后调试(或在程序正常退出后),pdb将 重新启动程序。自动重启会保留pdb的状态(例如 作为断点),并且在大多数情况下比退出 程序退出时进行调试。

请注意,在启动时,python将直接进入pdb模式,您需要先输入c然后输入enter才能开始运行脚本