Советы по отладке Python [закрыто]


164

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

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

Связанный


Ответы:


139

PDB

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

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

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

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

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

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

Pydb был написан как расширенная версия Pdb. Преимущества?


Вот статья об использовании pdb: sontek.net/debugging-python-with-pdb
sontek 29.10.10

Лично мне больше нравится ipdb .
Сардатрион - против злоупотребления SE

1
Видимо, есть переписать pydb под названием pydbgr
Ehtesh Choudhury

SublimeText имеет отличный плагин для добавления точек останова Python к коду: sublime.wbond.net/packages/Python%20Breakpoints
Деннис Голомазов

Если вы разрабатываете веб-приложение, просто добавьте представление для myserver.com/pdbв режиме отладки import pdb; pdb.set_trace(). Если вы используете Flask / Werkzeug с интерактивным отладчиком, вы также можете иметь представление, которое только что появилось assert False.
Ос

78

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

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

скриншот pudb

Хорошо для отладки автономных скриптов, просто запустите

python -m pudb.run my-script.py

Установите сpip install pudb
congusbongus

40

Если вы используете 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

Как вы определяете эти псевдонимы?
Casebash

9
Поместите этот материал в ~ / .pdbrc
Нед

на окнах вы можете поместить его в ~ / _ipython / ipythonrc.ini
быстрое умножение

33

логирование

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

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

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

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

РЕДАКТИРОВАТЬ: оригинальный 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


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

Ссылка "шаблон регистрации здесь" не работает. Пожалуйста обновите.
Йоханн

20

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

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

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

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

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


19

ipdb похож на pdb, с удивительным ipython.


5
Не могли бы вы добавить более подробную информацию о том, что он может сделать?
Casebash

17

print заявления

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

3
+1, когда каждый отладчик терпит неудачу, print - ваш друг, да, debug_print было бы хорошим дополнением
Anurag Uniyal

Обычно я печатаю сначала, а потом отлаживаю, за исключением случаев, когда я знаю , что смогу решить, отследив определенный раздел
Casebash

4
На самом деле модуль журнала делает именно это.
Э-Сат

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

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

16

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

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

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

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

15

PyDev

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

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


Есть ли у него возможность редактировать и продолжить?
Casebash

@ CaseBash нет, это не так, но эта функция запланирована. Даже без этого скорость и простота установки / сброса контрольных точек и просмотра значений переменных по-прежнему очень полезны
Jiaaro


12

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

Он имеет очень хороший отладчик на основе подсказок и графического интерфейса и поддерживает удаленную отладку.


@Casebash - добавил больше деталей
orip

1
+1 Это единственный отладчик Python, который я нашел, который может обрабатывать многопоточность.
Ли Нетертон

Будьте осторожны с его «обработкой» многопоточности - любое исключение в любом потоке приводит к зависанию всего процесса. Неплохо, если вы знаете об этом, очень больно, если нет
Уолт У.

Проект выглядит мертвым по состоянию на апрель 2014 года
Alojz Janez

7

В 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отображение напечатает трассировку (аналогично тому, который вы получаете, когда исключение всплывает на вершину стека). Я нашел это действительно полезным больше, чем несколько раз.


4

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

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


2

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

Есть несколько хитростей здесь . Это включает

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

2

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

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

Это сбросит всю исходную строку setup.py installвыполнения в execution.log.

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


1

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


1

Андреас Зеллер (Andreas Zeller ) предлагает полный онлайн-курс под названием « Отладка программного обеспечения », содержащий советы по устранению неполадок:

Краткое содержание курса

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

Зачем этот курс?

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

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

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

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


0

если вам нужен удобный графический способ печати стека вызовов в удобочитаемой форме, воспользуйтесь этой утилитой: 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))

Запустите с Джанго:

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.