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.