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

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

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

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

Ответы [ 5 ]

14 голосов
/ 02 марта 2010

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

import sys
import traceback

try:
    eval('a')
except NameError:
    traceback.print_exc(file=sys.stdout)
6 голосов
/ 02 марта 2010

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

4 голосов
/ 27 ноября 2011

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

Вы можете получить объект трассировки, используя 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

1 голос
/ 30 марта 2013

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

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

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

raiseErr()

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

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

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).

0 голосов
/ 02 марта 2010

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

...