try tipos sintaxis que print funciona excepciones example error ejemplos diferentes como catch python exception-handling jython

tipos - que es un error de sintaxis en python



¿Cómo capturar una excepción en python y obtener una referencia a la excepción, SIN saber el tipo? (3)

Me pregunto cómo puedo capturar cualquier objeto levantado (es decir, un tipo que no extienda la Exception ) y aún así obtener una referencia a él.

Encontré el deseo de hacer esto cuando uso Jython. Al llamar a un método Java, si ese método genera una excepción, no extenderá la clase de Exception de Python, por lo que un bloque como este no lo detectará:

try: # some call to a java lib that raises an exception here except Exception, e: # will never be entered

Puedo hacer esto, pero luego no tengo acceso al objeto de excepción que se generó.

try: # some call to a java lib that raises an exception here except: # will enter here, but there''s no reference to the exception that was raised

Puedo resolver esto importando el tipo de excepción de Java y capturándolo explícitamente, pero esto hace que sea difícil / imposible escribir envoltorios / decoradores genéricos para el manejo de excepciones.

¿Hay alguna forma de detectar alguna excepción arbitraria y aún así obtener una referencia a ella en el bloque de except ?

Debo tener en cuenta que espero que el decorador de manejo de excepciones que estoy haciendo sea utilizable para proyectos Python, no solo para proyectos Jython. Me gustaría evitar importar java.lang.Exception porque solo lo hace Jython-only. Por ejemplo, me imagino que puedo hacer algo como esto (pero no lo he intentado), pero me gustaría evitarlo si puedo.

try: # some function that may be running jython and may raise a java exception except (Exception, java.lang.Exception), e: # I imagine this would work, but it makes the code jython-only


FWIW, he encontrado que si agrega esta importación a su script Jython:

from java.lang import Exception

y simplemente use el controlador de excepciones de Python convencional:

except Exception, e:

capturará las excepciones de Python y las excepciones de Java


Puede hacer referencia a las excepciones utilizando el módulo sys . sys.exc_info es una tupla del tipo, la instancia y el rastreo.

import sys try: # some call to a java lib that raises an exception here except: instance = sys.exc_info()[1]


Solo para cualquier persona interesada ... Pasé un poco de tiempo probando cosas porque quería averiguar cómo obtener un seguimiento de pila adecuado si una Excepción de Python (de hecho, la BaseException, que es la clase base) o una java.lang.Throwable (se lanza la clase base de Java para Exception, Error, etc.) ... este código ilustra cómo capturar correctamente todas las referencias de números de línea.

import sys import traceback import java print "hello world" def custom_hook( type, exc, tb ): if isinstance( sys.exc_info()[ 1 ], java.lang.Throwable ): sys.stderr.write( "AS JAVA:/n" ) sys.exc_info()[ 1 ].printStackTrace() # java part else: sys.stderr.write( "NO JAVA TRACE:/n" ) sys.stderr.write( "AS PYTHON:/n" ) traceback.print_exc() # useful for custom exception handling! sys.excepthook = custom_hook def handle_exc(): # generate either a java.lang.Throwable (uncomment the next line and comment out "a = 16 / 0" # java.lang.String( None ) # OR... a python-style BaseException: a = 16 / 0 class Task( java.lang.Runnable ): def run( self ): # NB the problem with all this stuff is that the Java stack trace shows # a java.lang.Throwable occurring at the last line of this code block... # print "lots of stuff first" # print "lots 2" # handle_exc() # print "lots 3" # print "lots of stuff after" try: print "lots of stuff first" print "lots 2" handle_exc() print "lots 3" print "lots of stuff after" # NB do not catch both (Python) BaseException and java.lang.Throwable... # except ( BaseException, java.lang.Throwable ), e: # the above means that the line no. in handle_exc is not shown when a BaseException # is thrown... except java.lang.Throwable, t: tb = sys.exc_info()[ 2 ] sys.stderr.write( "java.lang.Throwable thrown at: %s/n" % tb.tb_lineno ) raise t java.awt.EventQueue.invokeAndWait( Task() )

Después de esto, se podría pensar en escribir un decorador para preceder a los métodos def run (self) y similares para que no tenga que escribir este bloque try-except catch-the-Throwable cada vez ... específicamente:

def throw_trap( function ): def wrapper(*args, **kvargs): try: return function( *args, **kvargs ) except java.lang.Throwable, t: tb = sys.exc_info()[ 2 ] while( tb ): sys.stderr.write( "thrown at: %s/n" % tb.tb_lineno ) tb = tb.tb_next raise t return wrapper def handle_exc(): java.lang.String( None ) # a = 16 / 0 class Task( java.lang.Runnable ): @throw_trap def run( self ): print "lots of stuff first" print "lots 2" handle_exc() print "lots 3" print "lots of stuff after" java.awt.EventQueue.invokeAndWait( Task() )