代码之家  ›  专栏  ›  技术社区  ›  jeremy

出错时自动启动python调试器

  •  166
  • jeremy  · 技术社区  · 17 年前

    这是一个我思考了很长时间的问题,但我从未找到合适的解决方案。如果我运行一个脚本,遇到一个索引错误,那么Python将打印错误的行、位置和快速描述,然后退出。遇到错误时是否可以自动启动PDB?我不反对在文件的顶部有一个额外的导入语句,也不反对有一些额外的代码行。

    13 回复  |  直到 8 年前
        1
  •  101
  •   Ivan Castellanos    8 年前

    你可以使用 traceback.print_exc 打印异常跟踪。然后使用 sys.exc_info 提取跟踪并最终调用 pdb.post_mortem 有追溯力

    import pdb, traceback, sys
    
    def bombs():
        a = []
        print a[0]
    
    if __name__ == '__main__':
        try:
            bombs()
        except:
            extype, value, tb = sys.exc_info()
            traceback.print_exc()
            pdb.post_mortem(tb)
    

    如果要使用 code.interact 使用产生异常的帧的局部变量

    import traceback, sys, code
    
    def bombs():
        a = []
        print a[0]
    
    if __name__ == '__main__':
        try:
            bombs()
        except:
            type, value, tb = sys.exc_info()
            traceback.print_exc()
            last_frame = lambda tb=tb: last_frame(tb.tb_next) if tb.tb_next else tb
            frame = last_frame().tb_frame
            ns = dict(frame.f_globals)
            ns.update(frame.f_locals)
            code.interact(local=ns)
    
        2
  •  334
  •   Antony Hatchkins Alexander Hamilton    8 年前
    python -m pdb -c continue myscript.py
    

    如果你不提供 -c continue 标记,然后在执行开始时需要输入“c”(用于继续)。然后它将运行到错误点,并给您控制。AS mentioned by eqzx ,此标志是python 3.2中的新添加项,因此对于早期的python版本,需要输入“c”(请参见 https://docs.python.org/3/library/pdb.html )

        3
  •  58
  •   compie Artelius    9 年前

    使用以下模块:

    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() # deprecated
            pdb.post_mortem(tb) # more "modern"
    
    sys.excepthook = info
    

    说出它的名字 debug (或者你喜欢的任何东西)把它放在你的python路径的某个地方。

    现在,在脚本的开头,只需添加 import debug .

        4
  •  32
  •   Latanius    13 年前

    伊皮松 具有用于切换此行为的命令: %PDB .它完全符合您所描述的,甚至更多(通过语法突出显示和代码完成为您提供更丰富的回溯信息)。这绝对值得一试!

        5
  •  31
  •   monkut    17 年前

    这不是调试器,但可能同样有用(?)

    我知道我在某个地方的演讲中听到吉多提到这个。

    我刚检查过巨蟒-?如果使用-i命令,则可以在脚本停止的位置进行交互。

    所以根据这个脚本:

    testlist = [1,2,3,4,5, 0]
    
    prev_i = None
    for i in testlist:
        if not prev_i:
            prev_i = i
        else:
            result = prev_i/i
    

    你可以得到这个输出!

    PS D:\> python -i debugtest.py
    Traceback (most recent call last):
      File "debugtest.py", line 10, in <module>
        result = prev_i/i
    ZeroDivisionError: integer division or modulo by zero
    >>>
    >>>
    >>> prev_i
    1
    >>> i
    0
    >>>
    

    老实说,我没有用过这个,但我应该用,看起来很有用。

        6
  •  16
  •   wodow    10 年前

    ipython在命令行中简化了这一点:

    python myscript.py arg1 arg2
    

    可重写为

    ipython --pdb myscript.py -- arg1 arg2
    

    或者,类似地,如果调用模块:

    python -m mymodule arg1 arg2
    

    可重写为

    ipython --pdb -m mymodule -- arg1 arg2
    

    注意 -- 阻止ipython将脚本的参数作为自己的参数读取。

    这还具有调用增强的IPython调试器(IPDB)而不是PDB的优势。

        7
  •  5
  •   Amandasaurus    15 年前

    您可以将此行放入代码中:

    import pdb ; pdb.set_trace()
    

    更多信息: Start the python debugger at any line

        8
  •  5
  •   Jehandad    9 年前

    如果您使用的是IPython环境,那么您只需使用%debug,shell将带您返回到与IPDB环境冲突的行进行检查等。上面提到的另一个选项是使用IPython magic%pdb,它有效地做到了这一点。

        9
  •  3
  •   Zlatko KarakaÅ¡    10 年前

    要使其运行而不必在开始时键入c,请执行以下操作:

    python -m pdb -c c <script name>
    

    pdb有自己的命令行参数:-c c将在执行开始时执行c(c ontinue)命令,并且程序将不间断运行,直到出现错误为止。

        10
  •  3
  •   Willemoes    8 年前

    如果您正在使用 ipython ,启动后类型 %pdb

    In [1]: %pdb
    Automatic pdb calling has been turned ON
    
        11
  •  2
  •   Hannah    9 年前

    python2.7中的python-m pdb script.py按“继续”以启动,它将运行到错误处并在那里中断以进行调试。

        12
  •  0
  •   vlad-ardelean    12 年前

    在层次结构中最顶层异常类的构造函数中放置一个断点,大多数情况下,您将看到错误出现在哪里。

    放置一个断点意味着你想要它意味着什么:你可以使用一个IDE,或者 pdb.set_trace ,或者什么

        13
  •  0
  •   blueFast    10 年前

    如果正在运行模块:

    python -m mymodule
    

    现在你想进入 pdb 发生异常时,请执行以下操作:

    PYTHONPATH="." python -m pdb -c c mymodule/__main__.py
    

    (或) 延伸 你的 PYTHONPATH )这个 Python路径 需要这样才能在路径中找到模块,因为您正在运行 PDB 模块现在。