当我使用IPython在Python中进行调试时,我有时会遇到一个断点,我想检查一个当前是生成器的变量.我能想到的最简单的方法就是将它转换为一个列表,但我不清楚在一行中这样做的简单方法是什么ipdb
,因为我对Python很新.
我正在使用firefox的jupyter(或Ipython)笔记本,并希望在单元格中调试一些python代码.我正在使用'import ipdb; ipdb.set_trace()'作为一种断点,例如我的单元格具有以下代码:
a=4
import ipdb; ipdb.set_trace()
b=5
print a
print b
Run Code Online (Sandbox Code Playgroud)
用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 …
Run Code Online (Sandbox Code Playgroud) 我经常使用ipdb,只是跳转到一段孤立的代码,即很难编写一个使用它的真实脚本.相反,我用模拟编写了一个最小的测试用例并跳转到它.
工作流程的示例:
def func():
...
import ipdb
ipdb.set_trace()
...
def test_case():
...
func()
...
Run Code Online (Sandbox Code Playgroud)
然后,调用
py.test test_file.py -s -k test_case
Run Code Online (Sandbox Code Playgroud)
现在,通常我只检查一个或两个变量,然后想要退出.更改代码并重新执行.
我该如何戒烟?手册说q
退出调试器.它(真的)没有.在调试器实际终止之前,您必须退出几次.Ctrl-C和Ctrl-D的相同行为(多次击中Ctrl-D的挫折最终也会退出终端).
是否有一种强制退出的聪明方法?这个工作流程是否合理?这样做的标准方法是什么?
我喜欢使用以下方法检查Python脚本中的错误:
$ python3 -m pdb my_script.py
Run Code Online (Sandbox Code Playgroud)
这让我进入了一个pdb提示符,从那里我可以c
继续执行,当它遇到错误时,我可以检查变量然后q
退出脚本执行以返回到我的shell.
我尝试使用iPython调试器模块,因为它更加丰富多彩:
$ python3 -m ipdb my_script.py
Run Code Online (Sandbox Code Playgroud)
但是,一旦检查完错误,我就无法退出调试器.使用q
quit命令只是在重新执行脚本和事后模式之间保持切换:
$ python3 -m ipdb my_script.py
ipdb> c
Uncaught exception. Entering post mortem debugging
Running 'cont' or 'step' will restart the program
ipdb> Inspect some variables at this point
ipdb> q
Post mortem debugger finished. The my_script.py will be restarted
ipdb> q
Uncaught exception. Entering post mortem debugging
Running 'cont' or 'step' will restart the program
ipdb> q
Post mortem debugger …
Run Code Online (Sandbox Code Playgroud) 在Visual Studio社区2015中,Visual C++项目在其Release文件夹中生成*.ipdb文件和*.iobj文件.
现在在Visual Studio社区2013中,我从未见过在项目Release文件夹中生成这些文件,所以我想知道 -
是否有可能停止生成它们?
我ipdb.set_trace()
在Python代码中使用了某个地方.是否可以使用IPDB命令忽略此断点?
clear
告诉我它清除了所有断点,但IPDB在它遇到障碍时再次停止ipdb.set_trace()
.
disable 1
告诉我:No breakpoint numbered 1
ignore 1
说:Breakpoint index '1' is not valid
澄清一下:当然我可以简单地从源代码中删除断点.但这需要退出调试器并再次启动它.通常需要大量工作才能到达某个地方并重新启动调试器会使生活变得更加困难.此外,如果存在一个巨大的循环并且您想要在循环中检查对象,最简单的方法是在对象之后直接在循环中放置一个断点.然后我怎么能跳过循环(以及所有数千个调用set_trace()
)并在循环使用后逐步执行代码next
?
最近在将调试器添加到我的python 2.7.10代码时,我得到以下消息:
Traceback (most recent call last):
File "/Users/isaachess/Programming/vivint/Platform/MessageProcessing/vivint_cloud/queues/connectors/amqplib_connector.py", line 191, in acking_callback
callback(message.body)
File "/Users/isaachess/Programming/vivint/Platform/MessageProcessing/vivint_cloud/queues/consumable_message_queue.py", line 32, in deserialized_callback
self._callback_method(msg)
File "/Users/isaachess/Programming/vivint/Platform/BusinessLogic/businesslogic/util/statsd_util.py", line 95, in _time_func
retVal = f(*args, **kwargs)
File "/Users/isaachess/Programming/vivint/Platform/MessageProcessing/vivint_cloud/net/router.py", line 226, in handle
try:
File "/Users/isaachess/Programming/vivint/Platform/MessageProcessing/vivint_cloud/net/router.py", line 226, in handle
try:
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/bdb.py", line 49, in trace_dispatch
return self.dispatch_line(frame)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/bdb.py", line 68, in dispatch_line
if self.quitting: raise BdbQuit
BdbQuit
Run Code Online (Sandbox Code Playgroud)
这是在插入行之后:
import pdb; pdb.set_trace()
在代码中.
我无法弄清楚为什么会这样.我已经阅读了Bdb和Bdbquit,但无法弄清楚为什么会在我的代码中发生这种情况.任何人都可以向我提供一些为什么会发生这种情况的提示吗?我真的想让调试器再次运行.
在Python 3中运行此代码后:
import pdb
def foo():
nums = [1, 2, 3]
a = 5
pdb.set_trace()
foo()
Run Code Online (Sandbox Code Playgroud)
以下表达式有效:
(Pdb) print(nums)
[1, 2, 3]
(Pdb) print(a)
5
(Pdb) [x for x in nums]
[1, 2, 3]
Run Code Online (Sandbox Code Playgroud)
但是以下表达式失败:
(Pdb) [x*a for x in nums]
*** NameError: global name 'a' is not defined
Run Code Online (Sandbox Code Playgroud)
以上在Python 2.7中运行良好.
这是一个错误还是我遗失了什么?
更新:查看新接受的答案.这确实是一个错误(或有问题的设计),现在通过在pdb中引入新的命令和模式来解决.
我用ipdb.set_trace()
,每当我需要设置我的代码一个破发点.现在,我正在尝试在我创建的过程中使用它multiprocessing
,而代码确实停止,我无法输入任何内容来继续调试.有没有办法让我的stdin
指导正常?
理想情况下,我想设想每次分叉进程停止调试时都会打开一个新的控制台,但我不认为这是可能的.
step
在使用pdb/ipdb调试器时,我可以在进入函数后退出一个函数吗?
如果没有这样的选择 - 什么是摆脱步入功能的最快方法?
ipdb ×10
python ×8
pdb ×5
debugging ×4
generator ×2
ipython ×2
python-2.7 ×2
cell ×1
exit ×1
jupyter ×1
python-3.x ×1
visual-c++ ×1
workflow ×1