2009-07-20 10 views

Respuesta

213

He aquí un ejemplo de conseguir la pila a través del módulo traceback, e imprimirla:

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 realmente sólo desea imprimir la pila a stderr, puede utilizar:

traceback.print_stack() 

O para imprimir en stdout (útil si desea mantener la salida redirigida), use:

traceback.print_stack(file=sys.stdout) 

Pero obtenerlo a través de traceback.format_stack() le permite hacer lo que quiera con él.

+8

Como cadena: 'stack_str = '' .join (traceback.format_stack())' – scottmrogowski

+0

Cómo hacer el mismo para todos los otros hilos * (I' estoy hablando de hilos que no controlo) *? – user2284570

+0

Tal vez me falta algo aquí, pero llamas a f, que el único propósito es llamar y no hacer nada más. Por qué – Chris

69
import traceback 
traceback.print_stack() 
+6

En realidad, me gusta 'traceback.print_exc()' que te proporciona casi lo mismo que habrías obtenido sin la instrucción 'except' (y también tiene menos codificación que la respuesta aceptada). – martineau

+22

'traceback.print_exc()' imprime el seguimiento de pila para cualquier excepción que pueda estar manejando, pero esto no resuelve la pregunta original, que es cómo imprimir la pila _current_ ("donde se encuentra ahora" en lugar de "donde su código fue cuando se disparó la última excepción, si hubo alguna ".) –

8

Si utiliza el depurador de Python, no solo el sondeo interactivo de variables sino que puede obtener la pila de llamadas con el comando "where" o "w".

Así que en la parte superior de su programa

import pdb 

Luego, en el código en el que desea ver lo que está sucediendo

pdb.set_trace() 

y te deja caer en un símbolo del

+0

He estado programando en Python durante más de una década. ¡Hay * así que * muchas veces podría haber usado esto! No puedo creer que ahora me estoy enterando. – hosford42

0

Aquí hay una variación de la excelente respuesta de @ RichieHindle que implementa un decorador que se puede aplicar de forma selectiva a las funciones como se desee. Funciona con Python 2.7.14 y 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()) 

de salida de la muestra:

test_func() called: 
    File "stacktrace_decorator.py", line 28, in <module> 
    print(test_func()) 
42 
Cuestiones relacionadas