¿Cómo se puede inspeccionar mediante progtwigción el seguimiento de stack de una excepción en Python?

Cuando ocurre una excepción en Python, ¿puedes inspeccionar la stack? ¿Puedes determinar su profundidad? He mirado el módulo de rastreo , pero no puedo averiguar cómo usarlo.

Mi objective es detectar cualquier excepción que ocurra durante el análisis de una expresión eval, sin detectar excepciones generadas por ninguna función a la que haya llamado. No me regañes por usar eval. No fue mi decisión.

NOTA: Quiero hacer esto programáticamente, no interactivamente.

Puede utilizar el módulo de inspección que tiene algunas funciones de utilidad para el seguimiento. Echa un vistazo a la descripción general de las propiedades de los objetos de marco.

traceback es suficiente, y supongo que la documentación lo describe bastante bien. Ejemplo simplificado:

 import sys import traceback try: eval('a') except NameError: traceback.print_exc(file=sys.stdout) 

Me gusta el módulo de rastreo.

Puede obtener un objeto de sys.exc_info() usando sys.exc_info() . Luego, puede usar ese objeto para obtener una lista preprocesada de entradas de rastreo utilizando traceback.extract_tb() . Luego, puede obtener una lista legible utilizando traceback.format_list() siguiente manera:

 import sys import traceback, inspect try: f = open("nonExistant file",'r') except: (exc_type, exc_value, exc_traceback) = sys.exc_info() #print exception type print exc_type tb_list = traceback.extract_tb(sys.exc_info()[2]) tb_list = traceback.format_list(tb_list) for elt in tb_list: print elt #Do any processing you need here. 

Consulte el módulo sys: http://docs.python.org/library/sys.html

y el Módulo de rastreo: http://docs.python.org/library/traceback.html

Usted define tal función ( doc aquí ):

 def raiseErr(): for f in inspect.stack(): print '-', inspect.getframeinfo(f[0]) 

y llámalo desde tus módulos para que:

 raiseErr() 

La función raiseErr imprimirá información sobre el lugar al que la llamaste .

Más elaborado, puedes hacerlo:

 import inspect, traceback A = [inspect.getframeinfo(f[0]) for f in inspect.stack()] print "traceback structure fields:", filter(lambda s: s[0] != '_', dir(A[0])) print A[0].filename, A[0].lineno for f in inspect.stack(): F = inspect.getframeinfo(f[0]) print '-', F.filename, F.lineno, '\t', F.code_context[0].strip() 

Otra posibilidad es definir esta función:

 def tr(): print '* - '*10, print sys._getframe(1).f_code.co_name 

Y llámalo en el lugar donde quieras la traza. Si desea todo el rastreo, _getframe(1) un iterador desde 1 en _getframe(1) .

Además de la respuesta de AndiDog acerca de inspect , tenga en cuenta que pdb permite navegar hacia arriba y hacia abajo de la stack, inspeccionar locales y cosas así. La fuente en la biblioteca estándar pdb.py podría ser útil para aprender cómo hacer tales cosas.