Форматирование исключения в Python для включения всех, кроме последних 'n' фреймов трассировки

Предположим, у вас была такая настройка:

def a():
    b()

def b():
    c()

def c():
    d()

def d():
    e()

Попытка позвонить a() приведет к следующей трассировке:

Traceback (most recent call last):
  File "<pyshell#181>", line 1, in <module>
    a()
  File "<pyshell#87>", line 2, in a
    b()
  File "<pyshell#90>", line 2, in b
    c()
  File "<pyshell#93>", line 2, in c
    d()
  File "<pyshell#96>", line 2, in d
    e()
NameError: name 'e' is not defined

Есть ли способ отформатировать исключение, чтобы оно включало только последний n кадры в трассировке? Например, если n = 2трассировка будет выглядеть так:

Traceback (most recent call last):
  File "<pyshell#93>", line 2, in c
    d()
  File "<pyshell#96>", line 2, in d
    e()
NameError: name 'e' is not defined

Я немного возился с этим и не могу придумать, как это сделать.

2 ответа

Решение

Начиная с Python 3.5, функции из модуляtraceback поддерживают отрицательные ограничения (исходное предложение было вдохновлено вашим вопросом и одобрено Guido):

import traceback

n = 2

try:
    a()
except:
    traceback.print_exc(limit=-n) # `n` last traceback entries

выходы

Traceback (most recent call last):
  File "/home/vaultah/test.py", line 8, in c
    d()
  File "/home/vaultah/test.py", line 11, in d
    e()
NameError: name 'e' is not defined

Вы можете повторить это поведение, даже если вы используете старый Python

import sys, traceback

n = 2

try:
    a()
except:
    ex = traceback.format_exception(*sys.exc_info())
    sys.stderr.write(''.join([ex[0]] + ex[-n-1:]))
    # or print(*[ex[0]] + ex[-n-1:], sep='', end='', file=sys.stderr)

Вывод будет точно таким же.

Модуль traceback имеет множество функций, которые вы должны помочь вам достичь того, что вы ищете. Специально, предельные варианты многих из этих функций

import traceback
def d():
    c()

def c():
    b()

def b():
    a()

def a():
    print traceback.extract_stack(limit=1)      

d()

Вернет кортеж, представляющий последний вызов

Другие вопросы по тегам