Запуск отладчика python автоматически при ошибке

Это вопрос, о котором я давно задумывался, но никогда не нашел подходящего решения. Если я запускаю script, и я сталкиваюсь, скажем, indexError, python печатает строку, местоположение и быстрое описание ошибки и завершает работу. Можно ли автоматически запускать pdb при возникновении ошибки? Я не против наличия дополнительного оператора импорта в верхней части файла, а также нескольких дополнительных строк кода.

Ответы

Ответ 1

Вы можете использовать traceback.print_exc для печати трассировки исключений. Затем используйте sys.exc_info для извлечения трассировки и, наконец, вызовите pdb.post_mortem с этой трассировкой.

import pdb, traceback, sys

def bombs():
    a = []
    print a[0]

if __name__ == '__main__':
    try:
        bombs()
    except:
        extype, value, tb = sys.exc_info()
        traceback.print_exc()
        pdb.post_mortem(tb)

Если вы хотите запустить интерактивную командную строку с code.interact, используя локали фрейма, где возникло исключение, вы можете сделать

import traceback, sys, code

def bombs():
    a = []
    print a[0]

if __name__ == '__main__':
    try:
        bombs()
    except:
        type, value, tb = sys.exc_info()
        traceback.print_exc()
        last_frame = lambda tb=tb: last_frame(tb.tb_next) if tb.tb_next else tb
        frame = last_frame().tb_frame
        ns = dict(frame.f_globals)
        ns.update(frame.f_locals)
        code.interact(local=ns)

Ответ 2

python -m pdb -c continue myscript.py

Если вы не указали флаг -c continue, вам нужно будет ввести 'c' (для продолжения), когда начнется выполнение. Затем он перейдет к точке ошибки и даст вам контроль. Как упомянутый eqzx, этот флаг является новым дополнением к python 3.2, поэтому для более ранних версий Python требуется ввод 'c' (см. https://docs.python.org/3/library/pdb.html).

Ответ 3

Используйте следующий модуль:

import sys

def info(type, value, tb):
    if hasattr(sys, 'ps1') or not sys.stderr.isatty():
    # we are in interactive mode or we don't have a tty-like
    # device, so we call the default hook
        sys.__excepthook__(type, value, tb)
    else:
        import traceback, pdb
        # we are NOT in interactive mode, print the exception...
        traceback.print_exception(type, value, tb)
        print
        # ...then start the debugger in post-mortem mode.
        # pdb.pm() # deprecated
        pdb.post_mortem(tb) # more "modern"

sys.excepthook = info

Назовите его debug (или как вам нравится) и поместите его где-нибудь в свой путь python.

Теперь, в начале вашего script, просто добавьте import debug.

Ответ 4

Ipython имеет команду для переключения этого поведения: % pdb. Он делает именно то, что вы описали, может быть, даже немного больше (дает вам более информативные обратные следы с подсветкой синтаксиса и завершением кода). Это определенно стоит попробовать!

Ответ 5

Это не отладчик, но, вероятно, такой же полезный (?)

Я знаю, что слышал, как Гвидо упоминал об этом в своей речи где-то.

Я только что проверил python -?, и если вы используете команду -i, вы можете взаимодействовать там, где остановлен ваш script.

Таким образом, данный script:

testlist = [1,2,3,4,5, 0]

prev_i = None
for i in testlist:
    if not prev_i:
        prev_i = i
    else:
        result = prev_i/i

Вы можете получить этот вывод!

PS D:\> python -i debugtest.py
Traceback (most recent call last):
  File "debugtest.py", line 10, in <module>
    result = prev_i/i
ZeroDivisionError: integer division or modulo by zero
>>>
>>>
>>> prev_i
1
>>> i
0
>>>

Честно говоря, я не использовал это, но я должен быть, кажется очень полезным.

Ответ 6

IPython делает это простым в командной строке:

python myscript.py arg1 arg2

можно переписать на

ipython --pdb myscript.py -- arg1 arg2

Или, аналогично, если вы вызываете модуль:

python -m mymodule arg1 arg2

можно переписать на

ipython --pdb -m mymodule -- arg1 arg2

Обратите внимание на --, чтобы остановить IPython от чтения аргументов script как собственных.

Это также имеет преимущество при вызове расширенного отладчика IPython (ipdb) вместо pdb.

Ответ 7

Если вы используете среду IPython, вы можете просто использовать отладчик%, и оболочка вернет вас в оскорбительную строку с помощью среды ipdb для проверок и т.д. Другой вариант, как указано выше, - использовать iPython magic% pdb который фактически делает то же самое.

Ответ 9

Если вы используете ipython, после запуска введите %pdb

In [1]: %pdb
Automatic pdb calling has been turned ON

Ответ 10

Чтобы он запускался без необходимости вводить c в начале, используйте:

python -m pdb -c c <script name>

Pdb имеет свои собственные аргументы командной строки: -c c выполнит команду c (ontinue) в начале выполнения, и программа будет работать без прерывания до ошибки.

Ответ 11

python -m pdb script.py в python2.7 нажмите продолжить, чтобы запустить, и он запустится до ошибки и сломается там для отладки.

Ответ 12

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

Помещение точки останова означает все, что вы хотите это означать: вы можете использовать IDE или pdb.set_trace или что-то еще

Ответ 13

Если вы используете модуль:

python -m mymodule

И теперь вы хотите ввести pdb при возникновении исключения, сделайте следующее:

PYTHONPATH="." python -m pdb -c c mymodule/__main__.py

(или расширьте PYTHONPATH). PYTHONPATH необходим, чтобы модуль был найден в пути, так как теперь вы запускаете модуль pdb.

Ответ 14

enter code here

Наибольшее = Нет Наименьшее = Нет пока Истина: num = input ("Введите число:"), если num == "done": break

try:
    ival = int(num)
except:
    print("Invalid input")
for value in [ival]:
    if smallest is None:
        smallest = value
    elif value < smallest:

        smallest = value
for value in [ival]:
    if largest is None:
        largest = value
    elif value > largest:

        largest = value

print ("Максимум есть", наибольший) print ("Минимум есть", наименьший)