使用ipdb在一个单元格中调试python代码(jupyter或Ipython)

时间:2016-02-24 21:14:12

标签: debugging cell jupyter ipdb

我正在使用firefox的jupyter(或Ipython)笔记本,并想在单元格中调试一些python代码。我正在使用'import ipdb; ipdb.set_trace()'作为断点的类型,例如我的单元格具有以下代码:

--------------------------------------------------------------------------
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.

用Shift + Enter执行后给出了这个错误:

{{1}}

如果我不在浏览器的jupyter笔记本中使用此代码,而是在jupyter qtconsole中,则会出现相同的错误。 这个错误意味着什么,以及如何避免它? 是否可以使用pdb调试器的next,continue等命令逐步调试单元格中的代码?

4 个答案:

答案 0 :(得分:87)

还有这个问题,它似乎与jupyter和ipdb的版本有关。

解决方法是使用它而不是ipdb库from IPython.core.debugger import Tracer Tracer()() #this one triggers the debugger 调用:

protocol ViewModel {
    var isActive: Bool { get }
}

struct TestViewModel: ViewModel {
    var isActive = false
}

protocol View {
    typealias V: ViewModel
    var viewModel: V { get }
}

struct TestView: View {
    var viewModel: TestViewModel
}

来源:http://devmartin.com/blog/2014/10/trigger-ipdb-within-ipython-notebook/

带注释的截图: screenshot illustrate how Tracer()() will cause Jupyter notebook to react. It pauses execution on the line in your code where you Trace()() and a new "inline" input accepts ipdb commands like 'p' or 'n' or 'c', shown here

答案 1 :(得分:12)

如果使用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')

答案 2 :(得分:9)

我的Jupyter版本是5.0.0,相应的ipython版本是6.1.0。我正在使用

import IPython.core.debugger
dbg = IPython.core.debugger.Pdb()
dbg.set_trace()

Tracer被列为已弃用。

更新

我尝试使用下面另一个答案https://stackoverflow.com/a/43086430/8019692中的方法,但收到了错误:

MultipleInstanceError: Multiple incompatible subclass instances of TerminalIPythonApp are being created.

我更喜欢我的方法 %% debug 魔法,因为我可以在其他单元格中定义的函数中设置断点并在另一个单元格中运行该函数。 Jupyter / IPython在我设置断点的函数中插入调试器,我可以使用通常的pdb命令。对他自己......

@ lugger1,已接受的答案已被弃用。

答案 3 :(得分:9)

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