2010-11-11 4 views
6

Una pregunta pitón novato: Necesito hacer lo siguientela forma de ejecutar algo si ocurre alguna excepción

try: 
    do-something() 
except error1: 
    ... 
except error2: 
    ... 
except: 
    ... 
#Here I need to do something if any exception of the above exception was thrown. 

que puede establecer un indicador y hacer esto. ¿Pero hay una manera más limpia de hacer esto?

+0

¿Qué tiene de malo establecer una bandera? Quiero decir, una declaración 'if' generalmente se considera inofensiva ... – detly

+1

+1 para una bandera. de lo contrario, confundirá las cosas con un nivel adicional de anidación. Quizás haya una mejor manera de estructurar el flujo del código para que no tenga que hacer esto en absoluto –

+0

@detly ¿Qué tiene de malo una bandera? Es fácil de manejar mal. Si puede reemplazar una solución de indicador con una mediante la estructuración, esto normalmente es una mejora. Entonces, sí, si no hay otro camino corto, entonces una bandera podría ser la única forma correcta de hacerlo, pero es un último recurso. – Alfe

Respuesta

2

Acabo de probar un par de ideas diferentes y parece que una bandera es tu mejor opción.

  • demás sólo suites se llama si no hay excepción
  • finalmente se llamará siempre a
+2

probablemente se establezca mejor en la cláusula else. – aaronasterling

1

A partir de los documentos: http://docs.python.org/reference/compound_stmts.html#finally

Si finalmente está presente, especifica un controlador de ‘limpieza’. La cláusula try se ejecuta, incluidas las cláusulas except y else. Si se produce una excepción en cualquiera de las cláusulas y no se maneja, la excepción se guarda temporalmente. La cláusula finally se ejecuta. Si hay una excepción guardada, se vuelve a subir al final de la cláusula finally. Si la cláusula finally genera otra excepción o ejecuta una declaración de devolución o interrupción, la excepción guardada se pierde. La información de excepción no está disponible para el programa durante la ejecución de la cláusula finally.

+6

El cuerpo de una cláusula 'finally' se ejecutará incluso si hay una excepción ** no **. No creo que esto sea lo que quiere el OP. – detly

+0

sí. finalmente se ejecutará siempre. Quiero algo como lo contrario de lo demás. – amit

0

No está claro si tiene que manejar de manera diferente error1, error2 etc. Si no es así, la siguiente código hará el truco:

try: 
    do_something() 
except (error1, error2, error3), exception_variable: 
    handle_any_of_these_exceptions() 

si es necesario para controlar errores diferentes de manera diferente, así como tener el código común, a continuación, en el bloque de excepción, puede hacer que el código del fol tipo lowing:

if isinstance(exception_variable, error1): 
     do_things_specific_to_error1() 
+0

necesito hacer cosas diferentes. usar isinstance parece unpythonic, pero definitivamente una opción. – amit

+0

@amit Generalmente estoy de acuerdo en que 'isinstance' es algo malo, pero' except' solo lo usa implícitamente con excepciones basadas en su tipo para empezar. Creo que es apropiado aquí. – aaronasterling

0

Esta es la mejor manera que se me ocurre. Parece un olor código embargo

try: 
    exception_flag = True 
    do-something() 
    exception_flag = False 
except error1: 
    ... 
except error2: 
    ... 
except: 
    ... 
finally: 
    if exception_flag: 
    ... 

Usted no necesita la finally si no está reraising excepciones en el controlador

2

Puede hacer esto con un anidado try. El except bloque del exterior try debe coger todas las excepciones Su cuerpo es otro try que inmediatamente vuelve a plantear la excepción. Los bloques except del interior try realmente manejan las excepciones individuales. Puede usar el bloque finally en el interior de try para hacer lo que desee: ejecutar algo después de cualquier excepción, pero solo después de una excepción.

Aquí hay un pequeño ejemplo interactivo (modelado en Applesoft BASIC para fines de nostalgia).

try: 
    input("]") # for Python 3: eval(input("]")) 
except: 
    try: 
     raise 
    except SyntaxError: 
     print "?SYNTAX", 
    except ValueError: 
     print "?ILLEGAL QUANTITY", 
    # additional handlers here 
    except: 
     print "?UNKNOWN", 
    finally: 
     print "ERROR" 
1

En realidad, no me gustan las banderas y las considero como la solución de último recurso. En este caso me gustaría considerar algo como esto:

def f(): 
    try: 
    do_something() 
    except E1: 
    handle_E1() 
    except E2: 
    handle_E2() 
    else: 
    return 
    do_stuff_to_be_done_in_case_any_exception_occurred() 

Por supuesto, esto es sólo una opción si se puede devolver en el caso else:.

Otra opción podría ser volver a lanzar la excepción y volver a detectarla para un manejo más general de los errores.Este podría ser incluso el enfoque más limpio:

def f(): 
    try: # general error handling 
    try: # specific error handling 
     do_something() 
    except E1: 
     handle_E1() 
     raise 
    except E2: 
     handle_E2() 
     raise 
    except (E1, E2): 
    do_stuff_to_be_done_in_case_any_exception_occurred() 
Cuestiones relacionadas