2014-09-04 4 views
0
42 -> for i in range(n): 
43  foo(i) 

Здесь я, в середине сессии pdb. Я хочу перейти к циклической итерации с i = k, не оценивая foo(i) для i < k, а затем продолжить вычислять foo(i) для i > k. Если я шаг вперед линию дляМожете ли вы перейти к n-й итерации в цикле?

42 for i in range(n): 
43 -> foo(i) 

набор i = k и continue, затем i восходит к 1 на следующей итерации. Могу ли я перевести его на k + 1?

+0

ли ответы на http://stackoverflow.com/questions/14139817/python-in-pdb-is-it-possible-to-enable-a-breakpoint-only-after- n-hit-counts работают для вас? – fredtantini

+0

@fredtantini: условная точка останова при i == k остановится в нужном месте, но не пропустит оценку циклов с i Ian

ответ

2

Вы не можете «пропустить вперед» и обратно, нет. Вы можете выполнить цикл только как написанный; чтобы добраться до итерации 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: 
+0

Пропустили ли это оценку foo (0), foo (1) и т. Д.? – Ian

+0

@Ian: нет, он будет запускать код как обычно. –

+0

@Ian: если вы хотите полностью изменить поток кода, вам придется изменить код. Отладка только позволяет выполнять код как написанный. –

0

я не могу проверить это прямо сейчас, но я считаю, что вы можете использовать команду: condition

состояние bpnumber [состояние]
Условие является выражением который должен оцениваться до истины до тех пор, пока не будет соблюдена точка останова. Если условие отсутствует, любое существующее условие удаляется; т. е. точка останова делается безусловной.

condition <insert line num> i == k

+0

OP хочет пропустить промежуточные итерации в целом. –

+0

@MartijnPieters А я вижу. Я оставлю это здесь, если это полезно кому-то другому, который хочет сделать то, что я описал. – KronoS