En Python, comment puis-je imprimer la pile d'appels en cours à partir d'une méthode (à des fins de débogage).
Voici un exemple d'obtention de la pile via le module traceback et de son impression:
import traceback
def f():
g()
def g():
for line in traceback.format_stack():
print(line.strip())
f()
# Prints:
# File "so-stack.py", line 10, in <module>
# f()
# File "so-stack.py", line 4, in f
# g()
# File "so-stack.py", line 7, in g
# for line in traceback.format_stack():
Si vous voulez uniquement imprimer la pile sur stderr, vous pouvez utiliser:
traceback.print_stack()
Ou pour imprimer sur la sortie standard (utile si vous souhaitez conserver la sortie redirigée ensemble), utilisez:
traceback.print_stack(file=sys.stdout)
Mais l'obtenir via traceback.format_stack()
vous permet de faire ce que vous voulez.
import traceback
traceback.print_stack()
inspect.stack()
renvoie la pile actuelle plutôt que l'exception traceback:
import inspect
print inspect.stack()
Voir https://Gist.github.com/FredLoney/5454553 pour une fonction utilitaire log_stack.
Si vous utilisez le débogueur Python, non seulement une analyse interactive des variables mais vous pouvez obtenir la pile d'appels avec la commande "where" ou "w".
Donc au sommet de votre programme
import pdb
Puis dans le code où vous voulez voir ce qui se passe
pdb.set_trace()
et vous êtes tombé dans une invite
Installer Inspect-it
pip3 install inspect-it --user
Code
import inspect;print(*['\n\x1b[0;36;1m| \x1b[0;32;1m{:25}\x1b[0;36;1m| \x1b[0;35;1m{}'.format(str(x.function), x.filename+'\x1b[0;31;1m:'+str(x.lineno)+'\x1b[0m') for x in inspect.stack()])
vous pouvez faire un extrait de cette ligne
il vous montrera une liste de pile d'appels de fonction avec un nom de fichier et un numéro de ligne
liste du début à l'endroit où vous mettez cette ligne
Voici une variante de l'excellente réponse de @ RichieHindle qui implémente un décorateur qui peut être appliqué de manière sélective aux fonctions à votre guise. Fonctionne avec Python 2.7.14 et 3.6.4.
from __future__ import print_function
import functools
import traceback
import sys
INDENT = 4*' '
def stacktrace(func):
@functools.wraps(func)
def wrapped(*args, **kwds):
# Get all but last line returned by traceback.format_stack()
# which is the line below.
callstack = '\n'.join([INDENT+line.strip() for line in traceback.format_stack()][:-1])
print('{}() called:'.format(func.__name__))
print(callstack)
return func(*args, **kwds)
return wrapped
@stacktrace
def test_func():
return 42
print(test_func())
Sortie de l'échantillon:
test_func() called:
File "stacktrace_decorator.py", line 28, in <module>
print(test_func())
42