26

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

有没有办法在import pdb; pdb.set_trace()抛出异常以检查本地堆栈时自动开始中断调试器()?

4

6 回答 6

25

你不想打破每一个异常;惯用的 Python 代码大量使用异常 (EAFP),因此您会不断地插入不相关的代码。

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

于 2013-09-23T13:20:58.833 回答
22

ipython 支持这一点(http://ipython.org)。从ipython内部,做

%pdb on

从那时起,每当您遇到异常时,它都会自动将您放入调试器中。

请注意,在一般使用中,您(可能)会很快厌倦...每次输入错误并出现语法错误时,您都必须退出调试器。但它有时很有用。

于 2013-09-23T14:57:26.923 回答
8

我在什么是使用 Python pdb 检查未处理异常原因的最简单方法是什么的答案中找到了我正在寻找的内容?

用它包装它:

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
于 2013-10-10T10:35:42.167 回答
7

对于 python 3(今天是 3.8),这可以通过

python3 -m pdb myscript.py

文档

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

注意,在启动时,python会直接进入pdb模式,需要输入cthenenter开始运行脚本

于 2020-12-10T09:26:15.667 回答
2

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

ipython --pdb <whatever command>
于 2020-12-02T05:49:55.537 回答
1

如果您只想包装函数的某些内部部分,或者需要装饰多个函数,则可以使用上下文管理器作为已接受答案的替代方案。我现在正在使用这个捕获所有异常的简单版本。我也建议使用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()

于 2019-06-08T11:45:01.203 回答