在iPython笔记本中,正确的调试方法是什么?

146

据我所知,%debug magic 可以在一个单元格内进行调试。

但是,我有跨越多个单元格的函数调用。

例如:

In[1]: def fun1(a)
           def fun2(b)
               # I want to set a breakpoint for the following line #
               return do_some_thing_about(b)

       return fun2(a)

In[2]: import multiprocessing as mp
       pool=mp.Pool(processes=2)
       results=pool.map(fun1, 1.0)
       pool.close()
       pool.join

我尝试过:

  1. 我尝试在cell-1的第一行设置%debug,但它会立即进入调试模式,甚至在执行cell-2之前就进入了调试模式。

  2. 我尝试在代码return do_some_thing_about(b)之前的行中添加%debug。 但然后代码会无限运行,永远不会停止。

在ipython笔记本中设置断点的正确方法是什么?


1
很遗憾,回答“不要使用Jupyter笔记本”不能算作一个答案。 - Gulzar
11个回答

110

您可以使用以下方式在jupyter中使用ipdb:

from IPython.core.debugger import Tracer; Tracer()()

编辑:自IPython 5.1版本起,上述函数已被弃用。以下是新的方法:


from IPython.core.debugger import set_trace

在需要断点的地方添加set_trace()。当输入字段出现时,键入help以获取ipdb命令。


23
Tracer”已被废弃。现在它的用法是:使用“from IPython.core.debugger import set_trace”,然后使用set_trace()调用断点。来源:https://davidhamann.de/2017/04/22/debugging-jupyter-notebooks/ - Anton Tarasenko
2
方便在需要的地方使用的一行代码:from IPython.core.debugger import set_trace;set_trace() - Nir

80

使用ipdb

通过以下方式安装

pip install ipdb

用法:

In[1]: def fun1(a):
   def fun2(a):
       import ipdb; ipdb.set_trace() # debugging starts here
       return do_some_thing_about(b)
   return fun2(a)
In[2]: fun1(1)

要逐行执行,请使用n,要进入函数,请使用s,要退出调试提示,请使用c

有关可用命令的完整列表,请参见:https://appletree.or.kr/quick_reference_cards/Python/Python%20Debugger%20Cheatsheet.pdf


ipdb在问题中提到的其他单元格中没有给我调试提示。现在代码一直在运行。 - Rex
@Rex 对我来说它有效。你把ipdb放在哪里了? 在return do_some_thing_about(b)这一行之前加入import ipdb; ipdb.set_trace();。然后从第二个单元格调用fun1(a),它应该可以工作。要退出调试提示,请使用“c”。 - Tevin Joseph K O
@Rex 更新了答案以提高清晰度。 - Tevin Joseph K O
36
这段代码在iPython控制台上可行,但在iPython笔记本上不行(这也是问题所在)。当我在笔记本单元格中键入import ipdb; ipdb.set_trace()时,它会显示MultipleInstanceError: Multiple incompatible subclass instances of TerminalIPythonApp are being created. - Bill
2
新手使用Jupyter...似乎它更适合演示和分享代码片段...我们是否可以拥有像Eclipse、RStudio等IDE提供的实际调试、逐步执行、断点、添加表达式和变量监视等功能。起初,似乎不是这样,只是想确认一下..... - Mahesha999
对我来说非常奇怪。有时候似乎可以工作,但并不总是如此。如果你忘记正确退出调试器,你可能会被卡在里面,被迫重新启动内核。绝对不是一个理想的解决方案... - Jean Paul

25

在Python 3.7中,您可以使用breakpoint()函数。只需输入

breakpoint()

在任何您想要运行时停止的地方,您都可以使用相同的pdb命令(r,c,n,...)或评估您的变量。


4
另外,当您调用breakpoint()时,可以在出现的文本框中键入"help"以获取命令列表。 - gbeaven
2
使用breakpoint()或pdb后似乎存在持续的挂起问题:https://github.com/ipython/ipython/issues/10516 - Dave Liu

18

你的返回函数在主函数(def function)的代码行中,你需要给它一个制表符。

请使用

%%debug 

取代

%debug 

希望能够调试整个单元格,而不仅仅是一行。也许这会对您有所帮助。


13

在你遇到错误后,在下一个单元格中只需运行%debug即可。


1
那真是太棒了! - Arco Bast
然而,我们可能希望在运行时通过设置一些断点来测试变量,在等待异常发生之前。 - Luk Aron
迄今为止,调试长时间运行的代码最实用的方法是: - ijoseph
你能详细说明并解释它的确切功能吗? - Nathan B
将在单元格下方打开一个调试器。如果您需要关于调试器的帮助,只需输入'h'。 - undefined

13

您可以在任何单元格中添加此内容:

import pdb; pdb.set_trace()

调试器将在该行停止。例如:

In[1]: def fun1(a):
           def fun2(a):
               import pdb; pdb.set_trace() # debugging starts here
           return fun2(a)

In[2]: fun1(1)

1
@Rex 不一定。ipdb 是 Python 调试器的重构版本,与 IPython 更紧密地集成。 pdb 是内置的。 - Two-Bit Alchemist
ipdb 也可以在 ipython shell 之外使用,并且带有一些方便的功能,如制表符完成。 - Jan

9
%pdb魔术命令也很有用。只需输入%pdb on,随后pdb调试器将在所有异常中运行,无论其在调用堆栈中深度如何。非常方便。
如果您想要调试特定的代码行,只需在那里引发异常(通常情况下您已经这样做了!)或使用其他人建议的%debug魔术命令。

8

好的回答。然而,我认为(我是Jupyter笔记本的新手)应该添加%debug来设置断点。 - Ad Infinitum
我所做的是将pdb.set_trace()复制并粘贴到我想要设置断点的位置,因为在Jupyter Notebook中b line_no无法正常工作,但在Python IDLE上可以正常使用。 - flowera
谢谢!我今天测试了一些截图,如果可以切换到Python IDLE,我会非常喜欢这样做。 - flowera
此外,我找到了一种在Jupyter Notebook上显示行号的方法,只需点击新行,然后按下l键即可。当然,您也可以编写自己的快捷方式,在Jupyter Notebook网站上提供了相关链接。 - flowera
1
我通常使用“p”来显示Jupyter笔记本中的命令列表。当我输入“show line numbers”时,该命令将出现在其中,并显示其快捷方式。您还可以学习要使用的命令的快捷方式。 - Ad Infinitum

6
我刚刚发现了PixieDebugger。虽然我还没有时间测试它,但它似乎是与ipython和ipdb相似的调试方式。

enter image description here

它还有一个“evaluate”选项卡。


3

作为JupyterLab的扩展部分,原生调试器现已可用。几周前发布了该调试器,用户可以通过获取相关扩展以及xeus-python内核(与ipykernel用户熟知的魔法函数不同)来安装它:

jupyter labextension install @jupyterlab/debugger
conda install xeus-python -c conda-forge

这使得使用其他IDE时熟悉的视觉调试体验成为可能。

enter image description here

来源: Jupyter的可视化调试器


1
xeus-python在我的Windows 10上无法运行。请查看我在github上的问题xeus-python issue on github - sergzemsk

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