TGTGInsighttelegram intelligenceLIVE / telegram public index
← Python Заметки
Python Заметки avatar

TGINSIGHT POST

Post #184

@pythonotes

Python Заметки

Views1,260Post view count
PostedNov 2711/27/2020, 09:00 AM
Post content

Post content

Делал оптимизацию своей библиотеки кеширования ответов от API. Нужно было выяснить, какие функции заставляют обращаться в API минуя кеш. Мне нужно было видеть полный стек вызова функции запроса в API. Конечно же первое что приходит в голову это traceback.print_stack(). Но мне не нравится его многословное форматирование. Поэтому я решил сделать свой аналог. Делается это совсем не сложно, достаточно посмотреть как работает функция print_stack() и сделать аналогично. Все дополнительные функции уже имеются в модуле traceback. Первым делом достаём фрейм frame = sys._getframe().f_back Теперь преобразуем его в стек вызовов stack = traceback.extract_stack(frame) Теперь у нас есть список инстансов класса FrameSummary в порядке их вызова. Остаётся сделать вывод for item in stack: print(f"{os.path.basename(item.filename)}[{item.lineno}] -> {item.name}") Получается что-то вроде такого __main__.py[123] -> <module> module1.py[456] -> func1 module2.py[789] -> func2 Как можно улучшить? 🔸 Фильтр по имени файла. Удобно при работе через дебагер, например, в Pycharm. Пропускаются ненужные вызовы. 🔸 Выводить передаваемые аргументы. Придется сделать свой extract_stack. 🔸 Добавить цвета Пример реализации здесь. Просто вызовите эту функцию в том месте где требуется увидеть цепочку вызовов. PS. Да, я знаю на сколько это странный способ дебага. Но такой инструмент потребовался под конкретную ситуацию и он справился хорошо. PPS: А теперь суровый хардкод! Всё в одну строку плюс некоторые дополнения в форматировании! (не повторяйте это дома!) print_stack_simple = lambda: print(*[f"{' ' * i}{os.path.basename(item.filename)}[{item.lineno}] -> {item.name}{'()' if not '>' in item.name else ''}" for i, item in enumerate(traceback.extract_stack(sys._getframe().f_back)[:-1])], sep='\n') #tricks