在Python中使用控制台断点调试

10
我正在尝试从Matlab转移到Python。 在调试时,Matlab的一个有用功能是可以在某些代码中设置断点并执行一些命令来调用该代码。 使用PyCharm + IPython,在Python中我尚未找到一种方式来做到这一点。 似乎我必须在调试模式下运行整个脚本才能进行任何调试,而不能像简单的命令那样进行。 我想我可以编写一个只包含我感兴趣的命令的一行脚本,但这似乎不是更好的方法。 Python的做法是什么?
7个回答

5
我推荐使用“Visual Studio 的 Python 工具集” (PTVS)。它是免费且开源的,尽管 Visual Studio 本身并非开源软件,但免费版本功能强大,可用于商业用途。此外,大多数学术机构的学生和教职员工通常可以免费获得 Visual Studio Ultimate。
如果您的程序在断点处停止,您可以打开 “Python Debug Interactive” (从工具 -> python 工具),它会打开一个交互式的 Python shell,在断点处访问您程序命名空间中所有可用变量,就像在 Matlab 中一样。
在源代码上悬停鼠标时,会显示变量的值;打开“locals”窗口更或多或少地模拟了 Matlab 中的工作区查看器,并且您还可以“观察”特定变量。我不知道通过此界面编辑变量是否安全,请谨慎使用!
不幸的是,PTVS 没有嵌套的断点,这是 Matlab 调试器中非常有用的功能。因此,如果您在断点处停止并从调试交互窗口调用方法,则该方法中的任何断点都将无法正常工作。请参见这个相关问题
与 Matlab 或 ipython 相比,调试 shell 中基于箭头键的命令历史记录相当简单,而且智能感知不如原生的 .net 语言。但是我已经连续使用它半年左右了,感觉和 Matlab 相比并没有太多缺失,除了优秀的文档。
还有一件事需要注意的是,在调试模式下执行代码的性能要慢得多,因此最好在不需要调试模式时运行您的代码(使用“Ctrl + F5”而不是“F5”)以获得最佳性能,或者如果您需要同时进行断点和良好的性能,则可以使用混合模式调试器

我刚刚编辑了这个答案,修复了一些损坏的链接,但实际上我已经多年没有使用 PTVS 了,因为它只适用于 Windows。如果你正在使用 Windows,它可能仍然是一个相当不错的选择,但我认为大多数人现在都使用 vscode,它也可以在其他平台上运行:https://code.visualstudio.com/docs/python/jupyter-support-py - Tim Rae

4

尝试使用 Python 调试器

b(reak) [[filename:]lineno | function[, condition]]

或者

pdb.set_trace();

更详细的教程可以在这里找到。


对于Python3.7+,您可以使用breakpoint(),请参见下面的我的回答 - user2987828

2

你尝试过Spyder吗?这是一个开源的IDE,外观与Matlab非常相似。它也提供了你想要的调试器。 https://code.google.com/p/spyderlib/

PS: 我也在迁移到Python,但我避免使用这样的东西,因为我想以空白的思维开始。:) 但我读了很多从Matlab到Numpy的文章...


1
是的,我看了一下。看起来是朝着正确方向迈出的一步,但远没有Matlab那样精细。我认为在未来几年中会有很多人从Matlab迁移到Python。为Python打造一个漂亮的用户友好的优秀环境以模拟Matlab,这是一个巨大的机遇。与Matlab不同,这并不需要对语言本身进行大量开发工作,只需要组合软件包并创建一个漂亮的IDE /研究环境。 - user1507844
PS: 我下载了Spyder :) 我很想要一个好的调试器,并且能够看到我的工作区变量。 - Eder Santana
你觉得与Matlab相比,它作为一个IDE怎么样?总的来说,你对Python有什么看法? - user1507844

2

我已从Matlab和R转向使用Python。我尝试过不同的编辑器,所以我可以给您一些建议。

1- Spyder是最接近Matlab的,但我的印象是它并不是很好。当我开始运行大量数据的长时间模拟时,它经常崩溃。 如果您刚开始学习Python,我建议您先使用这个编辑器一段时间,然后再考虑其他选择。

2- Emacs Python mode工作得非常好。我认为它难以配置,如果您对Python不熟悉,可能不是最佳选择。

3- PyCharm。我刚开始使用PyCharm,它似乎非常好(让我想起了RStudio)。我不认为它支持类似Spyder或Emacs内部交互式控制台的功能。 您仍然可以在调试模式下获得类似的体验。

4- 许多人喜欢IPython Notebook,但我认为它不适合编写较长的代码。如果您需要易于可视化的东西,那么它是一个不错的选择。


我一直在使用PyCharm,感觉非常满意。目前还有一些未解决的问题,例如添加对iPython、实时变量窗口等的支持,这将使其具备类似于Matlab或RStudio的功能,除了已经很棒的IDE之外。 - user1507844
你能使用交互式控制台吗? - Donbeo
是的,在我上次尝试绘制图形时它没有起作用,并且似乎在一些并行处理方面遇到了问题,但对于其他所有内容似乎都运行良好。 - user1507844

1

在控制台中创建函数,其中使用pdb.set_trace(),然后调试您想要的函数。

>>> import pdb

>>> def f():
...     pdb.set_trace()
...     my_function()
... 

然后调用创建的函数:
>>> f()
> <stdin>(3)f()
(Pdb) s
--Call--
> <stdin>(1)my_function()
(Pdb) 

愉快地调试吧 :)


0

在Python3.7+中设置永久断点,只需在源文件中插入表达式breakpoint()即可。不再需要导入任何东西,甚至是pdb。在非编译的Matlab中,相当于breakpoint()的语句是keyboard

总体来说,在Python的调试提示符(Pdb)(由breakpoint()显示)之后,您可以在类似于调试语句的Python语句前加上感叹号(!),而在Matlab的调试命令之后则以db开头以消除歧义,其中一些命令只能在调试提示符K>之后使用。

我也正在从Matlab迁移到Python。我习惯于在matlab -nodisplay内进行调试,并且正在切换到没有IDE的python3.10。这两者非常相似,如下表所示,这是一个与调试相关的罗塞塔石。

您可以使用命令tbb(Pdb)提示符下(或在您的文件$HOME/.pdbrc中)创建其他断点。与Matlab的对应物dbstop一样,您可以将它们设置为另一个文件、另一行,并让它们具有条件性。

这里是一个简短的罗塞塔石碑:

Python Python 可用的快捷键 Matlab
breakpoint() keyboard
where w dbstack
cont c dbcont
up u dbup
down d dbdown
step s dbstep
next n dbnext
print expression p expression expression
!nonlocal var;var= var=
break b dbstopdbstatus
clear cl dbclear
list l dbtype
display d 变量窗口
help h help
pp vars() save('b.mat');disp(load('b.mat'))
python -m pdb -c continuefilename.py dbstop if error

Matlab没有以下的等价物:

  • ignore n p (第n个断点只会在执行p次后触发提示)
  • prettyprint expression (快捷方式:pp)
  • jump codelinenumber (快捷方式:j)

我还不知道Python是否有可用于saveload的等效功能,除了pp vars()evalin(caller,expr)以及调试时的图形显示。


我想在“感叹号”之前添加“语句”,但目前Stack Overflow上有太多待处理的编辑 - user2987828

0

由于您提到正在使用 ipython,您也可以检查一下 ipdb

您需要先通过 pipeasy_install 安装它。例如:

pip install ipdb

使用方法与pdb相同。当您放置ipdb.set_trace()时,ipython控制台将弹出,您可以在其中检查/更改本地和全局变量,检查它们的文档和类型,进入传入函数的代码(使用“s”您将转到code123()的定义),等等。

import ipdb;

code000()
ipdb.set_trace();
code123()

另外一个提示是如何从ipython中获取?的功能(关于在调试器中获取函数和模块文档的方法)。这个答案


好的,谢谢。就像你说的那样工作。有没有办法让它与 IDE 的图形调试器一起工作?我习惯了 Matlab 中漂亮的图形调试器,而发现控制台调试器有点不友好... - user1507844
有一个叫做winpdb的工具。 - TheMeaningfulEngineer
抱歉,我误解了你的问题。不知道PyCharm是一个集成开发环境,以为它只是你在使用的某个框架 :) - TheMeaningfulEngineer
%run -d 可以让您在某个精确的行停止。请查看 %run? - Matt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接