ipython -pylab 调试:我能在特定行停止执行并进入shell吗?

5 投票
2 回答
4707 浏览
提问于 2025-04-16 16:30

在写Python代码的时候(主要是用到 numpy + matplotlib),我通常会在 vim 里直接输入代码,然后运行程序来测试:

python2 foo.py

有时候,当这种方式不够用,我需要更仔细地检查问题时,我会在ipython里启动程序:ipython -pylab foo.py,然后查看变量,测试一些命令等等。我喜欢 ipython,因为它有自动补全功能,还能使用 bash 命令。

这种方法对我来说一直挺好用,但现在我的程序变得更大了,里面有很多子程序(分布在多个文件中)。使用 ipython 的方法就不再适用了,因为它总是会运行 完整的代码,直到 foo.py 的最后一行(然后才进入pylab命令行)。我想要做的是,在某个子程序的特定行停止执行(可能是在另一个文件里),然后查看那里的变量。也就是说,我想设置一个断点,让pylab命令行在那时启动。

有没有什么 简单的方法 来调整我的 ipython 工作方式?比如,在 bar.py 的某一行停止:

ipython -pylab --stop-at bar.py:423 foo.py

或者,在 bar.py 的某个子程序名称处停止:

ipython -pylab --stop-at bar.py:subroutine-name foo.py

2 个回答

5

你可以在代码里引入pdb这个模块,然后在你想让代码暂停的地方加上pdb.set_trace()这一行。这样,Ipython就会进入一个可以互动调试的状态,你可以随意逐步查看你的代码是怎么运行的。

5

你可以通过在想要的位置插入以下代码来进入IPython调试会话:

import sys, IPython
IPython.Shell.IPShell(argv=[])
IPython.Debugger.Pdb(IPython.ipapi.get().options.colors).set_trace(sys._getframe())

这可能不是你想要的完全答案,但对我来说效果很好。它还让你很容易设置复杂的条件断点。网上有很多其他方法可以在你的源文件中启动IPython调试会话,但根据我的经验,这种方法在加载正确的颜色、自动补全等方面是最可靠的。

一旦调试会话开始,你可以使用break命令设置更多的断点:

ipdb> break test.py:11
Breakpoint 1 at /tmp/test.py:11
ipdb> b my_function
Breakpoint 2 at /tmp/test.py:5

为了方便插入,你可以在编辑器中设置一个宏或快捷键。我也是Vim用户,在我的vimrc文件中有以下键位映射:

nmap <C-P><C-D> oimport sys, IPython<CR>IPython.Shell.IPShell(argv=[])<CR>IPython.Debugger.Pdb(IPython.ipapi.get().options.colors).set_trace(sys._getframe())<ESC>:w<CR>

在正常模式下,按下Ctrl-P然后Ctrl-D,会在当前行之后插入调试代码,并且会保持正确的缩进,然后保存文件。

撰写回答