programa pila parentesis llaves imprimir funciones corchetes balanceados analizador algoritmo python exception-handling stack-trace

python - parentesis - Obtenga la descripción de la excepción y el seguimiento de la pila que causó una excepción, todo como una cadena



programa analizador de parentesis, llaves y corchetes "(){}[] " c++ (8)

Obtenga la descripción de la excepción y el seguimiento de la pila que causó una excepción, todo como una cadena

Para crear un stacktrace decentemente complicado para demostrar que obtenemos el stacktrace completo:

def raise_error(): raise RuntimeError(''something bad happened!'') def do_something_that_might_error(): raise_error()

Registrando el apilamiento completo

Una buena práctica es tener un registrador configurado para su módulo. Sabrá el nombre del módulo y podrá cambiar los niveles (entre otros atributos, como los controladores)

import logging logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__)

Y podemos usar este registrador para obtener el error:

try: do_something_that_might_error() except Exception as error: logger.exception(error)

Qué registros:

ERROR:__main__:something bad happened! Traceback (most recent call last): File "<stdin>", line 2, in <module> File "<stdin>", line 2, in do_something_that_might_error File "<stdin>", line 2, in raise_error RuntimeError: something bad happened!

Y así obtenemos la misma salida que cuando tenemos un error:

>>> do_something_that_might_error() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 2, in do_something_that_might_error File "<stdin>", line 2, in raise_error RuntimeError: something bad happened!

Consiguiendo solo la cuerda

Si realmente solo quieres la cadena, usa la función traceback.format_exc lugar, demostrando el registro de la cadena aquí

import traceback try: do_something_that_might_error() except Exception as error: just_the_string = traceback.format_exc() logger.debug(just_the_string)

Qué registros:

DEBUG:__main__:Traceback (most recent call last): File "<stdin>", line 2, in <module> File "<stdin>", line 2, in do_something_that_might_error File "<stdin>", line 2, in raise_error RuntimeError: something bad happened!

He visto muchas publicaciones sobre el seguimiento de la pila y las excepciones en Python. Pero no he encontrado lo que necesito.

Tengo un fragmento de código de Python 2.7 que puede provocar una excepción. Me gustaría capturarlo y asignar a una cadena su descripción completa y el seguimiento de la pila que causó el error (simplemente todo lo que usamos para ver en la consola). Necesito esta cadena para imprimirla en un cuadro de texto en la GUI.

Algo como esto:

try: method_that_can_raise_an_exception(params) except Exception as e: print_to_textbox(complete_exception_description(e))

El problema es: ¿cuál es la función complete_exception_description ?


Con Python 3, el siguiente código formateará un objeto de Exception exactamente como se obtendría usando traceback.format_exc() :

import traceback try: method_that_can_raise_an_exception(params) except Exception as ex: print(''''.join(traceback.format_exception(etype=type(ex), value=ex, tb=ex.__traceback__)))

La ventaja es que solo se necesita el objeto Exception (gracias al atributo __traceback__ registrado) y, por lo tanto, se puede pasar más fácilmente como argumento a otra función para su procesamiento posterior.


Consulte el módulo de format_exc() , específicamente la función format_exc() . Here

import traceback try: raise ValueError except: tb = traceback.format_exc() else: tb = "No error" finally: print tb


He definido la siguiente clase de ayuda:

import traceback class TracedExeptions(object): def __init__(self): pass def __enter__(self): pass def __exit__(self, etype, value, tb): if value : if not hasattr(value, ''traceString''): value.traceString = "/n".join(traceback.format_exception(etype, value, tb)) return False return True

Que luego puedo usar así:

with TracedExeptions(): #some-code-which-might-throw-any-exception

Y luego puede consumirlo así:

def log_err(ex): if hasattr(ex, ''traceString''): print("ERROR:{}".format(ex.traceString)); else: print("ERROR:{}".format(ex));

(Antecedentes: Me sentí frustrado por el uso de Promise s junto con Exception s, que desafortunadamente pasa las excepciones generadas en un lugar a un controlador on_rejected en otro lugar, y por lo tanto es difícil obtener el rastreo de la ubicación original)


Para aquellos que usan Python-3

Usando el módulo de traceback y la exception.__traceback__ uno puede extraer el seguimiento de pila de la siguiente manera:

  • agarrar la pila de seguimiento actual usando traceback.extract_stack()
  • elimine los últimos tres elementos (ya que son entradas en la pila que me llevaron a mi función de depuración)
  • agregue el __traceback__ del objeto de excepción usando traceback.extract_tb()
  • formatear todo usando traceback.format_list()

import traceback def exception_to_string(excp): stack = traceback.extract_stack()[:-3] + traceback.extract_tb(excp.__traceback__) # add limit=?? pretty = traceback.format_list(stack) return ''''.join(pretty) + ''/n {} {}''.format(excp.__class__,excp)

Una simple demostración:

def foo(): try: something_invalid() except Exception as e: print(exception_to_string(e)) def bar(): return foo()

Obtenemos la siguiente salida cuando llamamos bar() :

File "./test.py", line 57, in <module> bar() File "./test.py", line 55, in bar return foo() File "./test.py", line 50, in foo something_invalid() <class ''NameError''> name ''something_invalid'' is not defined


También puede considerar el uso del módulo Python cgitb , cgitb , para obtener información de excepción realmente buena y bien formateada, incluidos valores de variables locales, contexto de código fuente, parámetros de función, etc.

Por ejemplo para este código ...

import cgitb cgitb.enable(format=''text'') def func2(a, divisor): return a / divisor def func1(a, b): c = b - 5 return func2(a, c) func1(1, 5)

obtenemos esta salida de excepción ...

ZeroDivisionError Python 3.4.2: C:/tools/python/python.exe Tue Sep 22 15:29:33 2015 A problem occurred in a Python script. Here is the sequence of function calls leading up to the error, in the order they occurred. c:/TEMP/cgittest2.py in <module>() 7 def func1(a, b): 8 c = b - 5 9 return func2(a, c) 10 11 func1(1, 5) func1 = <function func1> c:/TEMP/cgittest2.py in func1(a=1, b=5) 7 def func1(a, b): 8 c = b - 5 9 return func2(a, c) 10 11 func1(1, 5) global func2 = <function func2> a = 1 c = 0 c:/TEMP/cgittest2.py in func2(a=1, divisor=0) 3 4 def func2(a, divisor): 5 return a / divisor 6 7 def func1(a, b): a = 1 divisor = 0 ZeroDivisionError: division by zero __cause__ = None __class__ = <class ''ZeroDivisionError''> __context__ = None __delattr__ = <method-wrapper ''__delattr__'' of ZeroDivisionError object> __dict__ = {} __dir__ = <built-in method __dir__ of ZeroDivisionError object> __doc__ = ''Second argument to a division or modulo operation was zero.'' __eq__ = <method-wrapper ''__eq__'' of ZeroDivisionError object> __format__ = <built-in method __format__ of ZeroDivisionError object> __ge__ = <method-wrapper ''__ge__'' of ZeroDivisionError object> __getattribute__ = <method-wrapper ''__getattribute__'' of ZeroDivisionError object> __gt__ = <method-wrapper ''__gt__'' of ZeroDivisionError object> __hash__ = <method-wrapper ''__hash__'' of ZeroDivisionError object> __init__ = <method-wrapper ''__init__'' of ZeroDivisionError object> __le__ = <method-wrapper ''__le__'' of ZeroDivisionError object> __lt__ = <method-wrapper ''__lt__'' of ZeroDivisionError object> __ne__ = <method-wrapper ''__ne__'' of ZeroDivisionError object> __new__ = <built-in method __new__ of type object> __reduce__ = <built-in method __reduce__ of ZeroDivisionError object> __reduce_ex__ = <built-in method __reduce_ex__ of ZeroDivisionError object> __repr__ = <method-wrapper ''__repr__'' of ZeroDivisionError object> __setattr__ = <method-wrapper ''__setattr__'' of ZeroDivisionError object> __setstate__ = <built-in method __setstate__ of ZeroDivisionError object> __sizeof__ = <built-in method __sizeof__ of ZeroDivisionError object> __str__ = <method-wrapper ''__str__'' of ZeroDivisionError object> __subclasshook__ = <built-in method __subclasshook__ of type object> __suppress_context__ = False __traceback__ = <traceback object> args = (''division by zero'',) with_traceback = <built-in method with_traceback of ZeroDivisionError object> The above is a description of an error in a Python program. Here is the original traceback: Traceback (most recent call last): File "cgittest2.py", line 11, in <module> func1(1, 5) File "cgittest2.py", line 9, in func1 return func2(a, c) File "cgittest2.py", line 5, in func2 return a / divisor ZeroDivisionError: division by zero


mis 2 centavos

import sys, traceback try: ... except Exception, e: T, V, TB = sys.exc_info() print ''''.join(traceback.format_exception(T,V,TB))


>>> import sys >>> import traceback >>> try: ... 5 / 0 ... except ZeroDivisionError, e: ... type_, value_, traceback_ = sys.exc_info() >>> traceback.format_tb(traceback_) ['' File "<stdin>", line 2, in <module>/n''] >>> value_ ZeroDivisionError(''integer division or modulo by zero'',) >>> type_ <type ''exceptions.ZeroDivisionError''> >>> >>> 5 / 0 Traceback (most recent call last): File "<stdin>", line 1, in <module> ZeroDivisionError: integer division or modulo by zero

Utiliza sys.exc_info () para recopilar la información y las funciones en el módulo de traceback para formatearla. Here hay algunos ejemplos para formatearlo.

La cadena de excepción completa está en:

>>> ex = traceback.format_exception(type_, value_, traceback_) >>> ex [''Traceback (most recent call last):/n'', '' File "<stdin>", line 2, in <module>/n'', ''ZeroDivisionError: integer division or modulo by zero/n'']