Советы по отладке Python

Каковы ваши лучшие советы по отладке Python?

Пожалуйста, не просто укажите конкретный отладчик, не сказав, что он действительно может сделать.

Связанный

  • Каковы хорошие способы сделать первый код Python первым? – В этом обсуждается минимизация ошибок

PDB

Вы можете использовать модуль pdb, вставить pdb.set_trace() любом месте, и он будет функционировать как точка останова.

 >>> import pdb >>> a="a string" >>> pdb.set_trace() --Return-- > <stdin>(1)<module>()->None (Pdb) pa 'a string' (Pdb) 

Для продолжения исполнения используйте c (или cont или continue ).

Можно выполнить произвольные выражения Python с помощью pdb. Например, если вы обнаружите ошибку, вы можете исправить код, затем введите выражение типа, которое будет иметь тот же эффект в текущем коде

ipdb – это версия pdb для IPython . Это позволяет использовать pdb со всеми функциями IPython, включая завершение табуляции.

Также возможно установить pdb для автоматического запуска на неперехваченное исключение.

Pydb был написан как усовершенствованная версия Pdb. Выгоды?

http://pypi.python.org/pypi/pudb , полноэкранный консольный Python-отладчик.

Его цель – предоставить все тонкости современных отладчиков на основе графического интерфейса в более легком и удобном для клавиатуры пакете. PuDB позволяет отлаживать код прямо там, где вы пишете и тестируете его – в терминале. Если вы работали с превосходными (но ныне древними) DOS-основанными Turbo Pascal или инструментами C, пользовательский интерфейс PuDB мог бы выглядеть знакомым.

pudb screenshot

Приятно отлаживать автономные скрипты, просто запускать

 python -m pudb.run my-script.py 

Если вы используете pdb, вы можете определить псевдонимы для ярлыков. Я использую следующие:

 # Ned's .pdbrc # Print a dictionary, sorted. %1 is the dict, %2 is the prefix for the names. alias p_ for k in sorted(%1.keys()): print "%s%-15s= %-80.80s" % ("%2",k,repr(%1[k])) # Print the instance variables of a thing. alias pi p_ %1.__dict__ %1. # Print the instance variables of self. alias ps pi self # Print the locals. alias pl p_ locals() local: # Next and list, and step and list. alias nl n;;l alias sl s;;l # Short cuts for walking up and down the stack alias uu u;;u alias uuu u;;u;;u alias uuuu u;;u;;u;;u alias uuuuu u;;u;;u;;u;;u alias dd d;;d alias ddd d;;d;;d alias dddd d;;d;;d;;d alias ddddd d;;d;;d;;d;;d 

логирование

Python уже имеет отличный встроенный модуль ведения журнала . Здесь вы можете использовать шаблон ведения журнала .

Модуль регистрации позволяет указать уровень важности; во время отладки вы можете регистрировать все, в то время как при нормальной работе вы можете регистрировать критические вещи только. Вы можете отключать и включать.

Большинство пользователей просто используют базовые операторы печати для отладки, а затем удаляют операторы печати. Лучше оставить их, но отключить их; то, когда у вас есть еще одна ошибка, вы можете просто снова включить все и посмотреть свои журналы.

Это может быть наилучшим способом отладки программ, которые нужно быстро выполнять, например, сетевых программ, которые должны реагировать до истечения срока действия сетевого соединения и уйти. У вас может не быть много времени для одноэтапного отладчика; но вы можете просто запустить свой код и занести в журнал все, затем порыться над журналами и выяснить, что происходит на самом деле.

EDIT: исходный URL-адрес шаблонов: http://aymanh.com/python-debugging-techniques

Эта страница отсутствует, поэтому я заменил ее ссылкой на моментальный снимок, сохраненный на сайте archive.org: http://web.archive.org/web/20120819135307/http://aymanh.com/python-debugging-techniques

Если он снова исчезнет, ​​вот те шаблоны, о которых я говорил. Это код, взятый из блога; Я этого не писал.

 import logging import optparse LOGGING_LEVELS = {'critical': logging.CRITICAL, 'error': logging.ERROR, 'warning': logging.WARNING, 'info': logging.INFO, 'debug': logging.DEBUG} def main(): parser = optparse.OptionParser() parser.add_option('-l', '--logging-level', help='Logging level') parser.add_option('-f', '--logging-file', help='Logging file name') (options, args) = parser.parse_args() logging_level = LOGGING_LEVELS.get(options.logging_level, logging.NOTSET) logging.basicConfig(level=logging_level, filename=options.logging_file, format='%(asctime)s %(levelname)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S') # Your program goes here. # You can access command-line arguments using the args variable. if __name__ == '__main__': main() 

И вот его объяснение, как использовать вышеизложенное. Опять же, я не получаю кредит на это:


По умолчанию модуль протоколирования печатает критические сообщения об ошибках и предупреждениях. Чтобы изменить это, чтобы напечатать все уровни, используйте:

 $ ./your-program.py --logging=debug 

Чтобы отправить сообщения журнала в файл debug.log, используйте:

 $ ./your-program.py --logging-level=debug --logging-file=debug.log 

Можно печатать, какие строки Python исполняются (спасибо Geo!). Это имеет любое количество приложений, например, вы можете изменить его, чтобы проверить, когда вызываются определенные функции или что-то вроде ##, чтобы отслеживать только определенные строки.

code.interact выводит вас в интерактивную консоль

 import code; code.interact(local=locals()) 

Если вы хотите иметь возможность легко получить доступ к истории консоли, посмотрите: « Могу ли я иметь механизм истории, например, в оболочке? » (Вам придется смотреть вниз).

Автозаполнение может быть включено для интерпретатора .

ipdb подобен pdb, с удивительностью ipython.

print заявлений

  • Некоторые люди рекомендуют функцию debug_print вместо печати для удобства отключения
  • Модуль pprint бесценен для сложных структур

очевидный способ отладки сценария

 python -m pdb script.py 
  • полезно, когда этот скрипт вызывает исключение
  • полезно при использовании команды virtualenv и pdb, не работает с версией venvs python.

если вы точно не знаете, где этот скрипт

 python -m pdb ``which <python-script-name>`` 

PyDev

PyDev имеет довольно хороший интерактивный отладчик. У этого есть выражения часов, зависания для оценки, списки потоков и стека и (почти) все обычные удобства, которые вы ожидаете от современного визуального отладчика. Вы даже можете подключиться к выполняемому процессу и выполнять удаленную отладку.

Как и другие визуальные отладчики, я считаю, что это полезно в основном для простых задач или для очень сложных проблем после того, как я пробовал все остальное. Я все еще делаю большую часть тяжелого подъема с заготовкой.

Если вы знакомы с Visual Studio, Python Tools для Visual Studio – это то, что вы ищете.

введите описание изображения здесь

Winpdb очень приятный, и вопреки его названию он полностью кросс-платформенный.

У него очень хороший отладчик на основе подсказок и GUI, а также поддержка удаленной отладки.

В Vim у меня есть три привязки:

 map <F9> Oimport rpdb2; rpdb2.start_embedded_debugger("asdf") #BREAK<esc> map <F8> Ofrom nose.tools import set_trace; set_trace() #BREAK<esc> map <F7> Oimport traceback, sys; traceback.print_exception(*sys.exc_info()) #TRACEBACK<esc> 

rpdb2 – удаленный отладчик Python, который можно использовать с WinPDB, сплошным графическим отладчиком. Потому что я знаю, что вы спросите, он может делать все, что я ожидаю от графического отладчика 🙂

Я использую pdb из nose.tools чтобы я мог отлаживать модульные тесты, а также обычный код.

Наконец, отображение F7 будет печатать трассировку (аналогично тому, как вы получаете, когда исключение пузырится до вершины стека). Я нашел его действительно полезным более чем несколько раз.

Определение полезных методов repr () для ваших классов (чтобы вы могли видеть, что такое объект) и использовать функции repr () или «% r»% (…) или «… {0! R} ..". Format (…) в ваших отладочных сообщениях / журналах является IMHO ключом к эффективной отладке.

Кроме того, отладчики, упомянутые в других ответах, будут использовать методы repr ().

Получение трассировки стека из запущенного приложения Python

Здесь есть несколько трюков. К ним относятся

  • Включение в интерпретатор / печать трассировки стека путем отправки сигнала
  • Получение трассировки стека из неподготовленного процесса Python
  • Запуск интерпретатора с флагами, чтобы сделать его полезным для отладки

Если вам не нравится проводить время в отладчиках (и не оценивайте плохое использование интерфейса командной строки pdb ), вы можете сбросить трассировку выполнения и проанализировать ее позже. Например:

 python -m trace -t setup.py install > execution.log 

Это приведет к тому, что все исходные строки setup.py install исполнение в execution.log .

Чтобы упростить настройку вывода трассировки и написать собственные трассировки, я собрал некоторые фрагменты кода в модуль xxtrace (public domain).

Когда это возможно, я отлаживаю использование Mx pdb в emacs для отладки исходного уровня.

Существует полный онлайн-курс под названием « Отладка программного обеспечения » Андреаса Целлера на Udacity, в котором есть советы по отладке:

Резюме курса

В этом классе вы узнаете, как систематически отлаживать программы, как автоматизировать процесс отладки и создавать несколько автоматических средств отладки в Python.

Зачем проходить этот курс?

В конце этого курса у вас будет четкое понимание систематической отладки, будет известно, как автоматизировать отладку, и в Python будет создано несколько функциональных средств отладки.

Предпосылки и требования

Требуются базовые знания программирования и Python на уровне Udacity CS101 или выше. Основное понимание объектно-ориентированного программирования полезно.

Настоятельно рекомендуется.

если вы хотите красивым графическим способом распечатать свой стек вызовов читаемым способом, ознакомьтесь с этой утилитой: https://github.com/joerick/pyinstrument

Выполнить из командной строки:

 python -m pyinstrument myscript.py [args...] 

Выполнить как модуль:

 from pyinstrument import Profiler profiler = Profiler() profiler.start() # code you want to profile profiler.stop() print(profiler.output_text(unicode=True, color=True)) 

Выполнить с django:

Просто добавьте pyinstrument.middleware.ProfilerMiddleware в MIDDLEWARE_CLASSES , а затем добавьте ?profile MIDDLEWARE_CLASSES в конец URL-адреса запроса, чтобы активировать профайлер.