Ответ 1
Хорошо, поскольку это, по-видимому, больше о том, какие стековые фреймы/стеки вызовов в общем случае позволяют пройти через это:
def f():
try:
g()
except:
# WE WILL DO THINGS HERE
def g():
h()
def h():
raise Exception('stuff')
#CALL
f()
def f():
try:
g()
except:
import inspect
import sys
#the third(last) item in sys.exc_info() is the current traceback object
return inspect.getinnerframes(sys.exc_info()[-1])
Это дает:
[(<frame object at 0xaad758>, 'test.py', 3, 'f', [' g()\n'], 0),
(<frame object at 0x7f5edeb23648>, 'test.py', 10, 'g', [' h()\n'], 0),
(<frame object at 0x7f5edeabdc50>, 'test.py', 13, 'h', [" raise Exception('stuff')\n"], 0)]
Как и ожидалось, три внутренних кадра f, g и h. Теперь мы можем взять этот последний объект кадра (один из h()
) и запросить его внешние кадры:
[(<frame object at 0x7f6e996e6a48>, 'test.py', 13, 'h', [" raise Exception('stuff')\n"], 0),
(<frame object at 0x1bf58b8>, 'test.py', 10, 'g', [' h()\n'], 0),
(<frame object at 0x7f6e99620240>, 'test.py', 7, 'f', [' return inspect.getinnerframes(sys.exc_info()[-1])\n'], 0),
(<frame object at 0x7f6e99725438>, 'test.py', 23, '<module>', ['print(inspect.getouterframes(f()[-1][0]))\n'], 0)]
Итак, вы идете, что все, что происходит: мы просто перемещаем стек вызовов. Для сравнения, здесь, что traceback.extract_stack(f()[-1][0])
дает:
[('test.py', 23, '<module>', 'print(traceback.extract_stack(f()[-1][0]))'),
('test.py', 7, 'f', 'return inspect.getinnerframes(sys.exc_info()[-1])'),
('test.py', 10, 'g', 'h()'),
('test.py', 13, 'h', "raise Exception('stuff')")]
Обратите внимание на инвертированный порядок здесь по сравнению с getouterframes
и уменьшенный вывод. На самом деле, если вы прищурились, это в основном выглядит как обычный трассировка (и, эй, это просто немного больше форматирования).
Подведение итогов: как inspect.getouterframes
, так и traceback.extract_stack
содержат всю информацию для воспроизведения того, что вы обычно видите в своей повседневной трассе; extract_stack
просто удаляет ссылки на фреймы стека, так как очень часто их больше не нужно, как только вы добираетесь до форматирования трассировки стека из-данного-кадра-наружу.