Durante la scrittura del codice, spesso desidero fare qualcosa del genere:
try:
foo()
except FooError:
handle_foo()
else:
try:
bar()
except BarError:
handle_bar()
else:
try:
baz()
except BazError:
handle_baz()
else:
qux()
finally:
cleanup()
Ovviamente, questo è completamente illeggibile. Ma sta esprimendo un'idea relativamente semplice: eseguire una serie di funzioni (o snippet di codice breve), con un gestore di eccezioni per ciascuna, e fermarsi non appena una funzione fallisce. Immagino che Python possa fornire zucchero sintattico per questo codice, forse qualcosa del genere:
# 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()
Se non vengono sollevate eccezioni, questo equivale a foo();bar();baz();qux();cleanup()
. Se vengono sollevate eccezioni, vengono gestite dal gestore delle eccezioni appropriato (se presente) e saltiamo su cleanup()
. In particolare, se bar()
genera un FooError
o BazError
, l'eccezione non viene catturata e si propagherà al chiamante. Questo è auspicabile, quindi rileviamo solo eccezioni che ci aspettiamo veramente di gestire.
Indipendentemente dalla bruttezza sintattica, questo tipo di codice è solo una cattiva idea in generale? Se sì, come lo rifattori? Immagino che i context manager possano essere usati per assorbire parte della complessità, ma non capisco davvero come funzionerebbe nel caso generale.