退出Python调试器ipdb

39

我经常使用ipdb,以一种跳转到隔离代码块的方式,也就是说这很难编写一个真正使用它的脚本。相反,我会编写一个最小化的测试用例,并进行跳转。

这是工作流程的示例:

def func():
   ...
   import ipdb
   ipdb.set_trace()
   ...

def test_case():
    ...
    func()
    ...

然后,调用

py.test test_file.py -s -k test_case

通常我只检查一两个变量,然后想要退出。更改代码然后重新开始。

如何退出?手册说q可以退出调试器。但它并没有真正退出。您必须多次退出才能使调试器实际终止。 Ctrl-C和Ctrl-D的行为相同(还有一个额外的烦恼是连续按几次Ctrl-D会导致终端也退出)。

有没有一种聪明的方式来强制退出?这种工作流程是否合理?标准的操作方式是什么?


3
我现在也遇到了这个问题。这是最近才出现的行为。以前它可以很好地执行 ctrl-c,但现在它就是无法退出。即使抛出异常也无法停止它。 - Chris Sattinger
2
关于这个问题的 GitHub issue 链接。 - Christian Long
原始问题已在ipython 5.2中得到解决,请参考@cheflo的答案。您能否接受它作为答案,以免混淆其他人的建议性解决方案? - Oleg Kuralenko
6个回答

55

以下方法适用于我:

import sys
sys.exit()

在较新的IPython版本中,正如上面和下面提到的,这种方法不起作用。 在这种情况下,

import os
os._exit(0)

应该仍然有效。


1
这对我没用。我只在控制台上得到“*** SystemExit:-1”,而且我仍然在ipdb中。 - Joseph Sheedy

44

我把以下内容放入了我的.pdbrc文件中。

import os

alias kk os.system('kill -9 %d' % os.getpid())

kk关闭调试器以及(触发调试器的进程)。


1
它可以工作,但看起来更像是解决问题的权宜之计。你试过问问ipdb的开发者吗?顺便说一下,这似乎是一个类似的问题https://dev59.com/_1kT5IYBdhLWcg3wFroT - Oleg Kuralenko
是的,我同意这是一个解决方法。这种解决方法的缺点之一是,如果您从ipython控制台使用%debug调用调试器并使用我的kk宏,它不仅会退出调试器,还会关闭ipython控制台。应该向开发人员提出此问题。 - Joachim
.pdbrc文件在哪里?如果它不存在,您必须创建它吗? - RubberDuckRabbit
如果os没有被导入,那么不应该是别名kk导入os;os.system('kill -9 %d' % os.getpid())吗? - alper
1
对于 Linux/Mac 和 Windows,代码如下:import os import platform terminate_cmd = 'kill -9 %d' % os.getpid() if platform.system() != 'Windows' else 'taskkill /F /PID %d' % os.getpid() alias kk os.system(terminate_cmd) - Jo Ja

7

如另一个答案中所提到的,这是IPython 5.1中的一个错误。它在此拉取请求中得到修复,并且从IPython 5.2开始不再是问题。现在您可以使用qquit()Ctrl+d退出调试器。


刚刚测试过了,对我来说运行得很好。我认为应该将其作为被接受的答案,因为从 ipython 5.2 开始,推荐的解决方法不再有意义。 - Oleg Kuralenko
@DarkStar1 在我的循环中它有效,请你发布一个不工作的示例吗? - joelostblom
我正在使用ipython 6.1.0和ipdb 0.10.3;如果跟踪设置在循环内部,q只会前进到循环的下一次迭代,我仍然必须使用os._exit(0)。 - thumbtackthief
@thumbtackthief 我刚刚再次测试了一下,当我在循环内部时退出调试器仍然可以正常工作。Python 3.6.4,IPython 6.2.1,ipdb 0.11,Linux。你能否提供一个你遇到问题的例子? - joelostblom
还有一个相关的问题:https://github.com/gotcha/ipdb/issues/111 - Ciro Santilli OurBigBook.com

7

这是最近版本的IPython 5.1.0的问题。您可以使用以下代码检查您的环境:

pip freeze | egrep -i '^i'

将 IPython 版本降级到 5.0.0 就可以解决这个问题。

pip install ipython==5.0.0

这对我来说没问题。

2

一种粗略但有效的方法是设置猴子补丁ipdb.set_trace = lambda:0,然后每次调用ipdb.set_trace时它将不执行任何操作并返回到调用函数。这样你就不必再输入q了。


当您不想实际“杀死”调用ipdb的进程时,这非常有用。这将使您保持在ipdb范围内,但会运行父进程直至完成。 - Victor Valente

0

我发现这些解决方案只会导致内核崩溃,然后你必须重新启动和加载所有内容。

我遇到的问题是在一个 for 循环中 q只是继续下一个迭代而不是退出循环。最终我弄清楚了,只有当你的 for 循环在 try 语句中时才会发生这种情况。删除 try,并且你可以再次退出调试器,而不会继续 for 循环。


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