使用 ipdb 在一个单元格中调试 python 代码(jupyter 或 Ipython)
Posted
技术标签:
【中文标题】使用 ipdb 在一个单元格中调试 python 代码(jupyter 或 Ipython)【英文标题】:using ipdb to debug python code in one cell (jupyter or Ipython) 【发布时间】:2016-06-07 09:32:58 【问题描述】:我正在使用带有 firefox 的 jupyter(或 Ipython)笔记本,并且想在单元格中调试一些 python 代码。我正在使用'import ipdb; ipdb.set_trace()' 作为一种断点,例如我的单元格有以下代码:
a=4
import ipdb; ipdb.set_trace()
b=5
print a
print b
使用 Shift+Enter 执行后会出现此错误:
--------------------------------------------------------------------------
MultipleInstanceError Traceback (most recent call last)
<ipython-input-1-f2b356251c56> in <module>()
1 a=4
----> 2 import ipdb; ipdb.set_trace()
3 b=5
4 print a
5 print b
/home/nnn/anaconda/lib/python2.7/site-packages/ipdb/__init__.py in <module>()
14 # You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.
15
---> 16 from ipdb.__main__ import set_trace, post_mortem, pm, run, runcall, runeval, launch_ipdb_on_exception
17
18 pm # please pyflakes
/home/nnn/anaconda/lib/python2.7/site-packages/ipdb/__main__.py in <module>()
71 # the instance method will create a new one without loading the config.
72 # i.e: if we are in an embed instance we do not want to load the config.
---> 73 ipapp = TerminalIPythonApp.instance()
74 shell = get_ipython()
75 def_colors = shell.colors
/home/nnn/anaconda/lib/python2.7/site-packages/traitlets/config/configurable.pyc in instance(cls, *args, **kwargs)
413 raise MultipleInstanceError(
414 'Multiple incompatible subclass instances of '
--> 415 '%s are being created.' % cls.__name__
416 )
417
MultipleInstanceError: Multiple incompatible subclass instances of TerminalIPythonApp are being created.
如果我不是在浏览器的 jupyter notebook 中使用此代码,而是在 jupyter qtconsole 中使用此代码,则会出现相同的错误。 这个错误是什么意思,如何避免它? 是否可以使用pdb调试器的next、continue等命令一步步调试cell中的代码?
【问题讨论】:
【参考方案1】:Tracer()
已弃用。
用途:
from IPython.core.debugger import set_trace
然后在需要断点的地方放置set_trace()
。
from IPython.core.debugger import set_trace
def add_to_life_universe_everything(x):
answer = 42
set_trace()
answer += x
return answer
add_to_life_universe_everything(12)
与仅使用内置 pdb 相比,这可以正常工作并为我们带来更多舒适(例如语法突出显示)。
source
【讨论】:
【参考方案2】:我的 Jupyter 版本是 5.0.0,我对应的 ipython 版本是 6.1.0。我正在使用
import IPython.core.debugger
dbg = IPython.core.debugger.Pdb()
dbg.set_trace()
Tracer
被列为已弃用。
更新:
我尝试使用下面另一个答案https://***.com/a/43086430/8019692 中的方法,但出现错误:
MultipleInstanceError: Multiple incompatible subclass instances of TerminalIPythonApp are being created.
我更喜欢我的方法而不是 %%debug 魔法,因为我可以在其他单元格中定义的函数中设置断点并在另一个单元格中运行该函数。 Jupyter/IPython 在设置断点的函数中放入调试器,我可以使用通常的pdb
命令。各有各的...
@lugger1,接受的答案已弃用。
【讨论】:
这个单线对我有用:from IPython.core.debugger import Pdb; Pdb().set_trace()
【参考方案3】:
也有这个问题,好像和jupyter和ipdb的版本有关。
解决办法是用这个代替ipdb库set_trace
调用:
from IPython.core.debugger import Tracer
Tracer()() #this one triggers the debugger
来源:http://devmartin.com/blog/2014/10/trigger-ipdb-within-ipython-notebook/
注释截图:
【讨论】:
谢谢罗伯特,这个解决方案似乎有效。我可以进入 ipdb 提示符,检查并打印我的变量。然而,任何继续 (c) 或执行下一条语句 (n) 的尝试只会杀死内核!每次我尝试这样做时,我只会在浏览器中看到“死内核”,或者在 qtconsole 中看到带有 SystemExit 异常的 sys.excepthook = old_excepthook。你有同样的问题吗? @lugger1 不,我没有这个问题。它对我来说很好。恐怕我不知道是什么原因造成的。升级版本? 这对我来说很好,并且不会杀死内核。谢谢罗伯特! Ctrl-D 不起作用,但exit
和 quit
都对我有用
Tracer()
已弃用。使用from IPython.core.debugger import set_trace
,然后在需要断点的地方放置set_trace()
。【参考方案4】:
如果使用 Jupyter Notebook 用魔法命令“%%debug”开始你的单元格。 然后 ipdb 行将显示在单元格的底部,这将帮助您浏览调试会话。以下命令应该可以帮助您入门:
n- 执行当前行并转到下一行。
c- 继续执行直到下一个断点。
确保每次决定调试时都重新启动内核,以便重新分配所有变量。您可以通过 ipdb 行检查每个变量的值,您将看到该变量未定义,直到您执行该行为该变量赋值。
%%debug
import pdb
from pdb import set_trace as bp
def function_xyz():
print('before breakpoint')
bp() # This is a breakpoint.
print('after breakpoint')
【讨论】:
我添加了一个代码,它解释了我们如何在 Jupyter notebook 中添加断点。import set_trace as bp
,这很有趣,set_trace()
确实感觉相当于设置断点:)以上是关于使用 ipdb 在一个单元格中调试 python 代码(jupyter 或 Ipython)的主要内容,如果未能解决你的问题,请参考以下文章