コードを書くとき、私はしばしばこのようなことをしたいです:
try:
foo()
except FooError:
handle_foo()
else:
try:
bar()
except BarError:
handle_bar()
else:
try:
baz()
except BazError:
handle_baz()
else:
qux()
finally:
cleanup()
明らかに、これは完全に判読できません。しかし、それは比較的単純なアイデアを表しています。一連の関数(または短いコードスニペット)を、それぞれに例外ハンドラーを付けて実行し、関数が失敗するとすぐに停止します。Pythonがこのコードに構文糖を提供できると思います。おそらく次のようなものです。
# 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()
例外が発生しない場合、これはと同等foo();bar();baz();qux();cleanup()
です。例外が発生した場合、それらは適切な例外ハンドラ(存在する場合)によって処理され、にスキップしcleanup()
ます。特に、またはbar()
が発生したFooError
場合BazError
、例外はキャッチされず、呼び出し元に伝播されます。これは望ましいことなので、本当に処理することを期待している例外のみをキャッチします。
構文の醜さに関係なく、この種のコードは一般的に単に悪い考えですか?もしそうなら、それをどのようにリファクタリングしますか?コンテキストマネージャーを使用して複雑さの一部を吸収できると思いますが、それが一般的なケースでどのように機能するかは本当にわかりません。
handle_*
ファンクションではどのようなことをしていますか?