可以在循环中跳到第n次迭代吗?
42 -> for i in range(n):
43 foo(i)
我现在正在使用pdb调试工具,想要直接跳到循环中当i = k
的那次迭代,而不想先执行foo(i)
当i
小于k
的部分,然后再继续执行foo(i)
当i
大于k
的部分。如果我向前一步到
42 for i in range(n):
43 -> foo(i)
设置i = k
,然后continue
,那么在下一次迭代时i
会回到1。我能不能让它直接跳到k + 1
呢?
2 个回答
1
我现在不能测试这个,但我相信你可以使用 condition
命令:
condition bpnumber [condition]
这里的条件是一个表达式,只有当它的结果为真时,断点才会生效。如果没有提供条件,那么就会移除任何已有的条件;也就是说,断点会变成无条件的。
condition <插入行号> i == k
4
你不能“跳过”某些步骤,也不能往回走。你只能按照写好的循环来执行;要到达第 k
次循环,你必须经过所有中间步骤。这是因为Python无法知道在不同的循环之间状态是否会发生大变化,所以你不能随便决定跳过某些循环。
不过,你可以在上下文中执行单独的表达式。比如,你可以运行 foo(k)
并观察返回的值。你甚至可以操作很多状态。只是你不能直接进入 for
循环使用的迭代器对象去跳过某些步骤。
如果在运行调试器之前修改测试代码是可行的,你可以和 for
循环共享迭代器:
r = range(n)
it = iter(r)
for i in it:
foo(i)
这样你就可以把 it
提前推进到某个点(比如用 next(it)
)。问题是,你不能像那样倒回去。
接下来的步骤是制作一个可以倒回的自定义迭代器:
class ControllableIterator(object):
def __init__(self, sequence):
self.pos = 0
self.seq = sequence
def __iter__(self): return self
def next(self):
try:
val = self.seq[self.pos]
except IndexError:
raise StopIteration
self.pos += 1
return val
__next__ = next # Python 3
然后使用这个:
r = range(n)
it = ControllableIterator(r)
for i in it:
foo(i)
在这里你可以把 it.pos
设置为不同的值,for
循环会顺利跟上。这 仅适用于序列,而不是任何可迭代对象。
演示:
$ bin/python test.py
> /Users/mj/Development/venvs/stackoverflow-2.7/test.py(19)<module>()
-> r = range(100)
(Pdb) l
14
15 def foo(i):
16 print i
17
18 import pdb; pdb.set_trace()
19 -> r = range(100)
20 it = ControllableIterator(r)
21 for i in it:
22 foo(i)
23
[EOF]
(Pdb) n
> /Users/mj/Development/venvs/stackoverflow-2.7/test.py(20)<module>()
-> it = ControllableIterator(r)
(Pdb)
> /Users/mj/Development/venvs/stackoverflow-2.7/test.py(21)<module>()
-> for i in it:
(Pdb)
> /Users/mj/Development/venvs/stackoverflow-2.7/test.py(22)<module>()
-> foo(i)
(Pdb)
0
> /Users/mj/Development/venvs/stackoverflow-2.7/test.py(21)<module>()
-> for i in it:
(Pdb)
> /Users/mj/Development/venvs/stackoverflow-2.7/test.py(22)<module>()
-> foo(i)
(Pdb)
1
> /Users/mj/Development/venvs/stackoverflow-2.7/test.py(21)<module>()
-> for i in it:
(Pdb) it.pos = 50
(Pdb) n
> /Users/mj/Development/venvs/stackoverflow-2.7/test.py(22)<module>()
-> foo(i)
(Pdb)
50
> /Users/mj/Development/venvs/stackoverflow-2.7/test.py(21)<module>()
-> for i in it: