【问题标题】:Is it possible to automatically break into the debugger when a exception is thrown?抛出异常时是否可以自动进入调试器?
【发布时间】:2013-09-23 13:16:26
【问题描述】:

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

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

【问题讨论】:

  • import pdb; pdb.set_trace()我们最喜欢的线路❤️

标签: python exception


【解决方案1】:

您不想在每个异常上都中断;惯用的 Python 代码大量使用异常 (EAFP),因此您会不断插入不相关的代码。

改为使用 pdb 事后分析:import pdb; pdb.pm()。这使用sys.last_traceback 来检查堆栈,包括在抛出点的本地人。

【讨论】:

  • 谢谢,我在解释器中工作得很好,就像documentation 中的示例一样,但是我如何在我的脚本中做到这一点?
  • @Framester 你把它放在你希望它中断的脚本中。 pdb.set_trace() 就像你在问题中所说的应该也可以,这是我通常使用的(不确定有什么区别)
  • 一个更有趣的问题陈述是“自动捕获会破坏程序的未捕获异常”,假设有一个精确的方法来定义它。
  • 这没有回答问题。我会决定我想做什么。
  • Python documentation for sys.last_traceback 声明“这三个变量并不总是被定义;”在这种情况下,使用 pdb.post_mortem 有时会有所帮助。
【解决方案2】:

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

%pdb on

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

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

【讨论】:

    【解决方案3】:

    我在What is the simplest way of using Python pdb to inspect the cause of an unhandled exception? 的回复中找到了我想要的东西

    用那个包裹它:

    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
    

    【讨论】:

    • 全局名称'functools'未定义
    • @KardiTeknomo import functools,是的,示例中缺少它
    【解决方案4】:

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

    python3 -m pdb myscript.py
    

    来自docs

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

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

    【讨论】:

    • 它将以 pdb.post_mortem() 的形式开始。有没有办法开始pdb.set_trace()?还是ipdb.set_trace()
    【解决方案5】:

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

    ipython --pdb <whatever command>
    

    【讨论】:

      【解决方案6】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多