Подтвердить что ты не робот

Как вы можете программно проверить трассировку стека исключения в Python?

Когда в Python возникает исключение, можете ли вы проверить стек? Можете ли вы определить его глубину? Я просмотрел модуль traceback, но я не могу понять, как его использовать.

Моя цель состоит в том, чтобы поймать любые исключения, возникающие во время разбора выражения eval, не перехватывая исключения, вызванные любыми функциями, которые он мог вызвать. Не ругайте меня за использование eval. Это не мое решение.

ПРИМЕЧАНИЕ. Я хочу сделать это программно, а не интерактивно.

4b9b3361

Ответ 1

Вы можете использовать модуль inspect, который имеет некоторые функции утилиты для трассировки. Посмотрите обзор свойств объектов фрейма.

Ответ 2

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

import sys
import traceback

try:
    eval('a')
except NameError:
    traceback.print_exc(file=sys.stdout)

Ответ 3

Мне нравится модуль трассировки.

Вы можете получить объект трассировки с помощью sys.exc_info(). Затем вы можете использовать этот объект для получения списка предварительно обработанных списков записей трассировки с помощью traceback.extract_tb(). Затем вы можете получить читаемый список, используя traceback.format_list() следующим образом:

import sys
import traceback, inspect

try:
    f = open("nonExistant file",'r')
except:
    (exc_type, exc_value, exc_traceback) = sys.exc_info()
    #print exception type
    print exc_type
    tb_list = traceback.extract_tb(sys.exc_info()[2])
    tb_list = traceback.format_list(tb_list)
    for elt in tb_list:
        print elt
        #Do any processing you need here.

См. модуль sys: http://docs.python.org/library/sys.html

и модуль трассировки: http://docs.python.org/library/traceback.html

Ответ 4

Вы определяете такую ​​функцию (doc здесь):

def raiseErr():
   for f in inspect.stack(): print '-', inspect.getframeinfo(f[0])

и назовите его из своих модулей так:

raiseErr()

Функция raiseErr будет печатать информацию о месте, которое вы назвали.

Более подробно вы можете сделать это:

import inspect, traceback
A = [inspect.getframeinfo(f[0]) for f in inspect.stack()]
print "traceback structure fields:", filter(lambda s: s[0] != '_', dir(A[0]))
print A[0].filename, A[0].lineno
for f in inspect.stack():
    F = inspect.getframeinfo(f[0])
    print '-', F.filename, F.lineno, '\t', F.code_context[0].strip()

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

def tr():
    print '* - '*10,
    print sys._getframe(1).f_code.co_name

И назовите его в том месте, где вы хотите отслеживать. Если вы хотите всю трассировку, сделайте итератор от 1 до _getframe(1).

Ответ 5

В дополнение к ответу AndiDog о inspect, обратите внимание, что pdb позволяет перемещаться вверх и вниз по стеку, проверять локальные жители и т.д. Источник в стандартной библиотеке pdb.py может помочь вам в обучении тому, как это делать.