【问题标题】:How to continue to the next loop iteration in Python PDB?如何继续 Python PDB 中的下一个循环迭代?
【发布时间】:2015-02-09 16:26:20
【问题描述】:

鉴于此示例代码:

import pdb

for i in range(10):
  pdb.set_trace()
  print(str(i))

当我从 PDB 收到提示时,如何使用 continue 循环控制语句跳过循环的迭代,当它也被 PDB 使用时,继续执行代码?

【问题讨论】:

  • 所以,要明确一点,您希望代码表现得好像执行了 continue 语句?您不希望 str(i) 为该循环打印,对吗?
  • 顺便说一句,对于“如何区分 pdb 命令和看起来像 pdb 命令的 Python 表达式?”的一般问题,您可以在 Python 表达式前加上感叹号。但这似乎不适用于continue
  • @MartijnPieters 如果在循环末尾添加 pass 语句,则可以跳转到循环末尾,然后继续,循环的下一次迭代将被正确初始化。
  • 谢谢大家!我也很欣赏凯文的评论,这是一种确认,这只能通过变通方法来完成。
  • @Dunes:当我意识到前进的唯一方法是在被跳过的语句之后有一些东西时,我产生了同样的想法。我在编辑和取消删除后看到您发布了相同的内容,对此感到抱歉。

标签: python debugging pdb


【解决方案1】:

您不能使用continue,因为调试器中的新语句需要完整并且在没有任何其他上下文的情况下有效; continue 必须在编译时在循环结构内给出。因此,即使调试器正在处理循环构造,也无法使用 !continue(使用 ! 以防止 pdb 解释命令)。

您可以使用j[ump] 命令,只要您有稍后 语句可以跳转到。如果在你想跳过的语句之后你的循环是空的,你只能'rewind':

$ bin/python test.py
> /.../test.py(5)<module>()
-> print(str(i))
(Pdb) l
  1     import pdb
  2     
  3     for i in range(10):
  4         pdb.set_trace()
  5  ->     print(str(i))
  6     
[EOF]
(Pdb) j 3
> /.../test.py(3)<module>()
-> for i in range(10):

j 3 跳转到第 3 行,没有跳过任何内容;将重新执行第 3 行,包括设置 range()。你可以跳到第 4 行,但是for 循环不会前进。

您需要在循环末尾添加另一个语句以跳转到 Python 继续。该语句可以是print()pass 或任何其他不必改变您的状态的东西。您甚至可以使用continue 作为最后一个语句。我用i

for i in range(10):
    pdb.set_trace()
    print(str(i))
    i  # only here to jump to.

演示:

$ bin/python test.py
> /.../test.py(5)<module>()
-> print(str(i))
(Pdb) l
  1     import pdb
  2     
  3     for i in range(10):
  4         pdb.set_trace()
  5  ->     print(str(i))
  6         i  # only here to jump to.
  7     
[EOF]
(Pdb) j 6
> /.../test.py(6)<module>()
-> i  # only here to jump to.
(Pdb) c
> /.../test.py(4)<module>()
-> pdb.set_trace()
(Pdb) s
> /.../test.py(5)<module>()
-> print(str(i))
(Pdb) j 6
> /.../test.py(6)<module>()
-> i  # only here to jump to.
(Pdb) i
1
(Pdb) c
> /.../test.py(4)<module>()
-> pdb.set_trace()
(Pdb) s
> /.../test.py(5)<module>()
-> print(str(i))
(Pdb) j 6
> /.../test.py(6)<module>()
-> i  # only here to jump to.
(Pdb) i
2

来自Debugger Commands

j(ump) lineno
设置将要执行的下一行。仅在最底部的框架中可用。这使您可以向后跳转并再次执行代码,或者向前跳转以跳过您不想运行的代码。

需要注意的是,并不是所有的跳转都是允许的——例如,不可能跳到for循环的中间或者跳出finally子句。

【讨论】:

  • j[ump] 不会跳过执行代码直到“跳转目标”?我在这里错过了什么?
  • @0xc0de continue 跳过执行循环的其余部分,所以这正是您需要的。但是,跳转到for重新启动循环,因此并不完全相同。在循环体末尾有一个虚拟语句将更接近continue 所做的:跳过循环体中的所有剩余语句,然后继续下一次迭代。
  • 啊,好吧,我错过了 OP 想跳过的内容。是否可以运行其余代码并在下一次(或任何进一步)迭代时停止?我一直在尝试使用unt[il],但无法通过它进行迭代。
  • @0xc0de until 存在于循环的out。我只是在循环语句或正文的第一条语句上添加一个断点,然后使用c
  • 是的,这就是我一直在做的,但想知道是否有更好的方法,当我想跳过一些迭代并针对特定条件(例如迭代中的特定值)进行调试时,不添加条件断点 (if value == 'debug-worthy':pdb.set_trace())。谢谢。
【解决方案2】:

听起来是一件很奇怪的事情。不过,您应该可以使用jump command。您可能需要在 for 循环的末尾添加一个 pass 语句,以便您可以跳转到循环的末尾。如果您不确定代码的行号,可以使用ll 找出循环的行号。

> c:\run.py(5)<module>()
-> print(i)
(Pdb) ll
  1     import pdb
  2     
  3     for i in range(10):
  4         pdb.set_trace()
  5  ->     print(i)
  6         pass
(Pdb) j 6
> c:\run.py(6)<module>()
-> pass
(Pdb) c
> c:\python\run.py(4)<module>()
-> pdb.set_trace()
(Pdb) c
1
> c:\python\run.py(5)<module>()
-> print(i)

值得注意的是,跳转到for 行会重新开始循环。

【讨论】:

  • 这是一个解决方案。非常感谢!虽然如果有人知道在上下文中执行 continue 语句的解决方案,那就更好了。
猜你喜欢
  • 2010-12-23
  • 2016-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多