22

有什么方法可以让 python 程序启动一个交互式调试器,import pdb; pdb.set_trace()而不是实际抛出异常?

我知道完成这项工作的难度,但它比巨大的堆栈跟踪更有价值,之后我必须使用它来确定在哪里插入断点,然后重新启动程序来调试它。我知道简单地启动调试器而不是抛出异常是没有意义的,因为任何异常都可以在一个级别或另一个级别上被捕获,所以如果我可以选择一个异常列表,一个交互式调试会话将启动而不是它们被抛出(因为我知道这个列表中的异常确实是“错误”,之后不会出现有意义的程序行为)......

我听说 Common Lisp 有这样的东西,但我不知道它是如何工作的,只是“真正的 lispers” 对它赞不绝口......

4

4 回答 4

18

最简单的方法是将整个代码包装在这样的try块中:

if __name__ == '__main__':

    try:
        raise Exception()
    except:
        import pdb
        pdb.set_trace()

有一个更复杂的解决方案用于sys.excepthook覆盖未捕获异常的处理,如 本节所述:

## {{{ http://code.activestate.com/recipes/65287/ (r5)
# code snippet, to be included in 'sitecustomize.py'
import sys

def info(type, value, tb):
   if hasattr(sys, 'ps1') or not sys.stderr.isatty():
      # we are in interactive mode or we don't have a tty-like
      # device, so we call the default hook
      sys.__excepthook__(type, value, tb)
   else:
      import traceback, pdb
      # we are NOT in interactive mode, print the exception...
      traceback.print_exception(type, value, tb)
      print
      # ...then start the debugger in post-mortem mode.
      pdb.pm()

sys.excepthook = info
## end of http://code.activestate.com/recipes/65287/ }}}

上面的代码应该包含在一个名为sitecustomize.pyinside site-packagesdirectory 的文件中,该文件由 python 自动导入。调试器仅在 python 以非交互模式运行时启动。

于 2012-11-01T10:01:01.023 回答
10

这个问题很老了,所以这主要是为了未来的我

try:
    ...
except:
    import traceback, pdb, sys
    traceback.print_exc()
    print ''
    pdb.post_mortem()
    sys.exit(1)
于 2016-06-26T17:47:05.763 回答
2

我写了一个包来在异常时启动 pdb。它接受@boreis-gorelik 的回答,并在运行时修改解释器状态,因此无需更改代码:

安装

 pip install mort

用法

mort <file.py or module to execute>

发生异常时,pdb repl 应在给定终端中启动

于 2018-04-17T04:54:17.930 回答
1

如果你在 REPL 里面,你可以做

import sys
import pdb
pdb.post_mortem(sys.last_traceback)

请参阅https://docs.python.org/2/library/pdb.htmlhttps://docs.python.org/3/library/traceback.html

于 2016-04-01T15:13:57.990 回答