Cuando escribo código, a menudo quiero hacer algo como esto:
try:
foo()
except FooError:
handle_foo()
else:
try:
bar()
except BarError:
handle_bar()
else:
try:
baz()
except BazError:
handle_baz()
else:
qux()
finally:
cleanup()
Obviamente, esto es completamente ilegible. Pero está expresando una idea relativamente simple: ejecutar una serie de funciones (o fragmentos de código cortos), con un controlador de excepción para cada una, y detenerse tan pronto como una función falle. Me imagino que Python podría proporcionar azúcar sintáctico para este código, quizás algo como esto:
# NB: This is *not* valid Python
try:
foo()
except FooError:
handle_foo()
# GOTO finally block
else try:
bar()
except BarError:
handle_bar()
# ditto
else try:
baz()
except BazError:
handle_baz()
# ditto
else:
qux()
finally:
cleanup()
Si no se generan excepciones, esto es equivalente a foo();bar();baz();qux();cleanup(). Si se generan excepciones, las maneja el manejador de excepciones apropiado (si corresponde) y pasamos a cleanup(). En particular, si bar()aumenta un FooErroro BazError, la excepción no se detectará y se propagará a la persona que llama. Esto es deseable por lo que solo detectamos excepciones que realmente esperamos manejar.
Independientemente de la fealdad sintáctica, ¿es este tipo de código una mala idea en general? Si es así, ¿cómo lo refactorizaría? Me imagino que los gestores de contexto podrían usarse para absorber parte de la complejidad, pero realmente no entiendo cómo funcionaría eso en el caso general.
handle_*funciones?