Ответ 1
Вы можете использовать модуль inspect, который имеет некоторые функции утилиты для трассировки. Посмотрите обзор свойств объектов фрейма.
Когда в Python возникает исключение, можете ли вы проверить стек? Можете ли вы определить его глубину? Я просмотрел модуль traceback, но я не могу понять, как его использовать.
Моя цель состоит в том, чтобы поймать любые исключения, возникающие во время разбора выражения eval, не перехватывая исключения, вызванные любыми функциями, которые он мог вызвать. Не ругайте меня за использование eval. Это не мое решение.
ПРИМЕЧАНИЕ. Я хочу сделать это программно, а не интерактивно.
Вы можете использовать модуль inspect, который имеет некоторые функции утилиты для трассировки. Посмотрите обзор свойств объектов фрейма.
traceback
достаточно - и я полагаю, что документация описывает его довольно хорошо. Упрощенный пример:
import sys
import traceback
try:
eval('a')
except NameError:
traceback.print_exc(file=sys.stdout)
Мне нравится модуль трассировки.
Вы можете получить объект трассировки с помощью 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
Вы определяете такую функцию (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)
.
В дополнение к ответу AndiDog о inspect
, обратите внимание, что pdb
позволяет перемещаться вверх и вниз по стеку, проверять локальные жители и т.д. Источник в стандартной библиотеке pdb.py
может помочь вам в обучении тому, как это делать.