【问题标题】:Simpler way to put PDB breakpoints in Python code?在 Python 代码中放置 PDB 断点的更简单方法?
【发布时间】:2011-10-22 06:50:28
【问题描述】:

只是一个方便的问题。我对 Visual Studio 和 XCode 等 IDE 中的调试器有点宠坏了。我发现必须输入 import pdb; pdb.set_trace() 来设置断点有点笨拙(我宁愿不要在文件顶部导入 pdb,因为我可能会忘记并保留它)。

有没有更简单的方法在 Python 代码中设置断点,就像您在 IDE 中看到的一样简单明了?

【问题讨论】:

  • 使用 PyCharm。除了使用 Python IDE 运行,怎么可能比进入断点行简单?
  • 只需使用python -m pdb <your_script>.py 然后b <line_number> 在所选行号设置断点(无函数括号)。点击c 继续到你的断点。您可以单独使用b 命令查看所有断点。键入 help 以查看调试时可用的其他 pdb 命令。
  • 从 Python 3.7 开始,您现在可以使用内置的 breakpoint() 函数。 python.org/dev/peps/pep-0553

标签: python pdb


【解决方案1】:

您可以使用支持 python 调试的 IDE,或者您可以查看出色的 Winpdb 工具。它适用于任何平台,并为您的 python 脚本提供图形调试工具。

http://winpdb.org/

【讨论】:

    【解决方案2】:

    你可以使用:

    • 机翼理念
    • 带有 pydev 插件的eclipse
    • pycharms

    以上所有都支持从 IDE 内部进行 python 调试。

    【讨论】:

      【解决方案3】:

      你可以通过运行从命令行运行你的程序到pdb

      python -m pdb your_script.py

      它将在第一行中断,然后您可以使用break 命令在代码中的任意位置添加断点,其语法为:

      b(reak) [[文件名:]lineno |函数[, 条件]]

      它足够灵活,让您能够在任何地方添加断点。

      【讨论】:

      • 为了澄清这一点,如果我pdb.set_trace() 并进入调试器,使用l 命令(列表)并看到我想在第 27 行设置断点,然后我会输入:b 27 并且调试器会在第 27 行设置断点(我发现文档有点难以理解,所以想添加说明点)。
      • 另外,如果你有一个对象x,并且你想在它的方法f被调用时停止,你可以说break x.f,然后c(ontinue)。即使对象在不可访问的文件中或者是动态创建的,这也有效,例如通过 unpickling。
      • 在堆栈跟踪后调试时,您可以将完整路径复制到模块并附加行号,如b /data/users/me/project/env/local/lib/python2.7/site-packages/django/core/urlresolvers.py:596
      • 如果您无法访问代码怎么办?想象一下,您安装了一个第三方应用程序,它崩溃了,您需要知道原因。那么pdb怎么用呢?
      【解决方案4】:

      在 vim 中,我为此设置了一个宏(在我的 .vimrc 文件中):

      map <silent> <leader>b oimport pdb; pdb.set_trace()<esc>
      map <silent> <leader>B Oimport pdb; pdb.set_trace()<esc>
      

      所以我可以只按 \b (不处于插入模式时),它会在当前行之后添加一个断点,或者 \B (注意大写),它会在当前行之前放置一个。

      这似乎工作正常。大多数其他“简单”程序员编辑器(emacs、sublimetext 等)应该有类似的简单方法来做到这一点。

      编辑: 我其实有:

      au FileType python map <silent> <leader>b oimport pdb; pdb.set_trace()<esc>
      au FileType python map <silent> <leader>B Oimport pdb; pdb.set_trace()<esc>
      

      仅对 python 源文件打开它。您可以很容易地为 javascript 或您使用的任何其他语言添加类似的行。

      2019 年更新(Python 3.7+)**

      Python 3.7+ 现在有内置的 breakpoint() 可以替换 vim 中以前的 import pdb; pdb.set_trace()。它仍然有效。

      2021 年更新

      所以这些天我做了很多 django,我也在使用 ipdb 调试器,带有一些 javascript 和一些 HTML 模板,所以现在有:

      function InsertDebug()
          if &filetype == "python"
              execute "normal! oimport ipdb;ipdb.set_trace()\<esc>"
          elseif &filetype == "javascript"
              execute "normal! odebugger;\<esc>"
          elseif &filetype == "html" || &filetype == "htmldjango"
              execute "normal! o{% load debugger_tags %}{{ page\|ipdb }}\<esc>4bcw"
          else
              echoerr "Unknown filetype - cannot insert breakpoint"
          endif
      endfunction
      nmap <leader>b <esc>:call InsertDebug()<CR>
      

      所以我得到了ipdb 断点,或者这些语言中的其他语言断点。然后这也很容易扩展到其他语言。我认为可以使用更好的自动命令来做到这一点 - 但我无法让它像这样可靠地工作。

      【讨论】:

      • 不错的解决方案,如果您的 .vimrc 文件中有 set autoindent,添加的行也将具有正确的缩进。
      • 是的,我不明白为什么大多数发行版没有将set autoindent(以及许多其他选项)作为标准。我对新系统做的第一件事就是引入更好的 vimrc...
      • 只需使用一个名为 register 的 vim!按"dyy 保存要缓冲“d”的行(如debug),并在需要时执行"dp"dP。学习vim registers!它们非常有用且始终受到支持!
      • 之后如何添加:w?
      • 将命名寄存器的概念再进一步,您可以录制宏,执行必要的操作,然后停止宏。然后将宏内容粘贴到您的 vimrc 文件中。例如,以qd 开始宏,然后以"dp 粘贴。最后将您的指令分配给一个寄存器,以便始终在 vim 加载时填充。示例:let @d = 'oimport pdb; pdb.set_trace()k0:w' 现在,只要您想将行粘贴到文件中,只需使用 @d。上面也保存了文件。但是您必须自己记录(而不是在上面复制/粘贴),因为涉及特殊字符(用于转义等)。
      【解决方案5】:

      在脚本上运行调试器的最简单方法就是

      pdb your_script.py
      

      在 Linux 命令行上运行 pdb 会给出

      usage: pdb.py scriptfile [arg] ...
      

      【讨论】:

      • 如何安装pdb?还是从哪里来的?
      【解决方案6】:

      你可以使用:

      from pdb import set_trace as bp
      
      code
      code
      bp()
      code
      code
      

      【讨论】:

      • 不确定为什么会有多余的别名,但是 ;-)。出于某种原因,我的 IDE/编辑器(vscode)在这个 AM 上是一头母马,并不断强调。看到你的评论真的帮助了我。祝你有美好的一天!
      • 我如何才能强制导入set_trace 仅当我使用 bp() 时?
      【解决方案7】:

      如果您不想在每次运行程序时手动设置断点(在 Python 3.2+ 中),例如假设你想直接在第 3 行创建一个断点并在那里停止执行:

      python -m pdb -c "b 3" -c c your_script.py

      以下信息可能会有所帮助:

      如果文件 .pdbrc 存在于用户的主目录或当前目录中,它将被读入并执行,就好像它是在调试器提示符下键入的一样。这对于别名特别有用。如果两个文件都存在,则首先读取主目录中的文件,并且本地文件可以覆盖其中定义的别名。

      在 3.2 版中更改:.pdbrc 现在可以包含继续调试的命令,例如 continue 或 next。以前,这些命令无效。

      3.2 版中的新增功能:pdb.py 现在接受 -c 选项,该选项执行的命令就像在 .pdbrc 文件中给出的一样,请参阅调试器命令。

      【讨论】:

      • Python 2.7 怎么样?
      • @Friedrich 自 2020 年 1 月 1 日起,不再支持 Python 2。您可能可以安装一些反向移植,但是,如果您要安装第 3 方库,我建议您使用pudb(Python 2 的版本为 2019.2 或更早版本)。
      【解决方案8】:

      这就是在命令行中使用 pdb 而不在源代码中实现任何内容的方式(文档和其他在线资源不能很好地向过去只使用可视化调试器的程序员解释这一点) :

      通过在 shell 提示符下键入以下内容来启动 pdb:

      python -m pdb 'python_script'
      

      此命令初始化 pdb,pdb 调试器将在您的 python_script 的第一行中断并等待您的输入:

      (Pdb)
      

      这是与调试器通信的接口。现在,您可以在此处指定您的命令。与在可视化调试器中使用按钮或键盘快捷键相反,在这里您将使用命令来获得相同的结果。

      您可以通过命令“n”(下一个)转到代码中的下一行:

      (Pdb) n
      

      执行 next 会显示行号,以及源代码中的具体代码:

      > python_script(line number)method name
      -> current line in the source code
      

      您可以通过在源代码中指定行号来设置断点。

      (Pdb) b 50
      

      这里,调试器设置为在第 50 行中断。如果没有任何其他断点,则第 50 行的断点将是第一个断点,它可以通过断点 id 引用,在这种情况下为 1。如果您添加更多断点,它们将按顺序获得标识符(即 2、3 等)

      一旦设置断点,您将继续执行程序,直到 pdb 到达断点,如下所示:

      (Pdb) c
      

      一旦你到达一个断点,你可以转到下一行,如前所述使用 n 命令。如果要检查变量的值,可以执行参数命令如下:

      (Pdb) p variable_name
      

      如果不再需要断点,可以通过 clear 命令传入断点的 id 来清除它:

      (Pdb) clear 1
      

      最后,当您完成调试器后,您可以像退出 python 命令行解释器一样退出执行。

      (Pdb) exit()
      

      我希望这将帮助任何人开始使用 pdb。以下是您可以与调试器一起使用的命令列表:pdb so question and answers

      【讨论】:

        【解决方案9】:

        在 Atom 中,如果安装了 Python 插件,您只需输入“pdb”并回车,sn-p 将输入 import 并为您回溯。

        我现在已经习惯了,有时我只是输入它,即使我在 vim 中编辑它并等待下拉菜单出现。

        【讨论】:

          【解决方案10】:

          我还没有尝试过,但他们只是在 Python 3.7 中实现了a new built-in called breakpoint(),这意味着您现在可以使用一条语句插入断点:

          breakpoint()
          

          【讨论】:

          • 我可以确认这适用于 3.9 谢谢
          【解决方案11】:

          Python 3.7 有一种新的内置方式来设置断点。调用

          breakpoint()
          

          更多https://stackoverflow.com/a/53263117/6488361

          【讨论】:

          【解决方案12】:

          一个被低估的方法是直接在pdb中设置断点:

          pdb> b torch/__init__:10
          

          将在site-packages\torch\__init__.py:10上设置断点

          然后pdb&gt; c 将在此断点处停止。

          以下也是有效的:

          pdb> b d:\anaconda\lib\site-packages\torch\__init__.py:10
          pdb> b torch\__init__.py:10
          pdb> b d:\\anaconda\\lib\\site-packages\\torch\\__init__.py:10
          pdb> b d:/anaconda/lib/site-packages/torch/__init__.py:10
          

          详情请见doc

          【讨论】:

            【解决方案13】:

            您可以使用带有Python-Mode 插件的Vim 或带有Elpy 插件的Emacs。

            这些插件通过简单的击键为您提供断点(Vim 中的\ b 和 Emacs 中的C-c C-u b)以及来自重量级 IDE 的许多其他功能(代码折叠、重构、linting 等)——所有这些都在一个轻量级的范围内—— weight 基于终端的文本编辑器。

            【讨论】:

              【解决方案14】:

              在运行过程中保存断点、别名和其他设置的最简单方法是在与脚本相同的文件夹中使用 .pdbrc,然后以 python -m pdb &lt;scriptname&gt;.py 运行脚本

              像在 pdb 中一样输入命令,每行一个。 例如:

              .\.pdbrc
              --------
              b 12
              display var
              c
              

              【讨论】:

                【解决方案15】:

                有了这个sn -p断点可以自动设置:

                import pdb
                import sys
                try:
                    from io import StringIO           # Python3
                except:
                    from StringIO import StringIO     # Python2
                
                bp = 14    # or e.g. "submodule.py:123"
                
                sys.stdin = StringIO('break %s\ncont\n' % bp)
                pdb.set_trace()
                sys.stdin = sys.__stdin__   # reset to usually stdin
                
                print(1)     # lineno 14
                print(2)
                

                此方法适用于 Python 2 和 3。

                也可以通过.pdbrc 文件(本地或家庭)设置断点并即时操作。尽管如此,cont 命令还是不能手动执行。 因此,由于pdb.set_trace 需要标准输入,上述代码只是以编程方式将命令“重定向”到标准输入。

                将代码放在主程序中并结合argparse,可以从命令行传递断点,并进一步停止直到断点。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-09-15
                  • 1970-01-01
                  • 1970-01-01
                  • 2017-04-12
                  • 2013-08-27
                  • 1970-01-01
                  相关资源
                  最近更新 更多