2009-04-07 3 views
8

Из того, что я могу сказать, pdb не распознает, когда исходный код изменился между «запусками». То есть, если я отлаживаю, заметьте ошибку, исправьте эту ошибку и перезапустите программу в pdb (т. Е. Не выйдя из pdb), pdb не будет перекомпилировать код. Я все равно буду отлаживать старую версию кода, даже если pdb перечисляет новый исходный код.Как заставить pdb признать, что источник изменился между прогонами?

Так что, pdb не обновляет скомпилированный код при изменении источника? Если нет, есть ли способ сделать так? Я хотел бы иметь возможность остаться в одном сеансе pdb, чтобы сохранить свои точки останова и т. Д.

FWIW, gdb заметит, когда программа отлаживает изменения под ним, хотя и только при перезапуске этой программы. Это поведение, которое я пытаюсь воспроизвести в pdb.

ответ

2

Что вы подразумеваете под "повторением программы в pdb?" Если вы импортировали модуль, Python не будет перечитывать его, если вы явно не попросите сделать это, то есть с reload(module). Однако reload далеко не пуленепробиваемый (см. xreload для другой стратегии).

Есть много подводных камней в перезагрузке кода Python. Чтобы более решительно решить вашу проблему, вы можете обернуть pdb классом, который записывает вашу информацию о точке прерывания в файл на диске, например, и воспроизводит их по команде.

(К сожалению, игнорировать первую версию этого ответа, это рано, и я не прочитал ваш вопрос достаточно тщательно.)

+0

Что я имею в виду «перекладки» является концептуально, что я имею в виду, перезапустив программу питона из командная строка. pdb ясно понимает, что моя программа выходит, поэтому мне интересно, когда она запускает мою программу во второй раз, если я могу заставить ее также перекомпилировать источник по мере необходимости. – user88028

+0

Вы можете попробовать использовать 'reload' изнутри pdb перед тем, как перезапустить его, но опять же, в зависимости от структуры вашей программы, он может быть ненадежным. (FWIW, я считаю это самым большим провалом Python в качестве языка. Исходя из таких сред, как Smalltalk и Lisp, это просто удручает.) –

+0

@NicholasRiley Я хотел бы включить xreload в качестве команды в отладчиках ppanon trepan (trepan3k https: //pypi.python.org/pypi/trepan3k и trepan2 https://pypi.python.org/pypi/trepan2). Это GPL3. Это нормально? Вы автор? – rocky

3

Следующая мини-модуль может помочь. Если вы импортировать его в PDB сессии, то вы можете использовать:

pdb> pdbs.r() 

в любое время, чтобы принудительно перезагрузить все несистемные модули кроме основного. Код пропускает это, потому что он выдает ImportError («Невозможно перезапустить внутренний модуль main ') исключение.

# pdbs.py - PDB support 

from __future__ import print_function 

def r(): 
    """Reload all non-system modules, so a pdb restart 
    will reload anything new 
    """ 
    import sys 
    # This is likely to be OS-specific 
    SYS_PREFIX = '/usr/lib' 

    for k, v in sys.modules.items(): 
     if not hasattr(v, '__file__'): 
      continue 
     if v.__file__.startswith(SYS_PREFIX): 
      continue 
     if k == '__main__': 
      continue 
     print('reloading %s [%s]' % (k, v.__file__)) 
     reload(v) 
+0

Когда я запускаю pdb.r(), я получаю: *** AttributeError: объект 'dict' не имеет атрибута 'iteritems' – Chelmite

+0

Мои извинения - .iteritems() несовместим с Python 3.x. Я изменил код, чтобы он работал. – pourhaus

Смежные вопросы