Python 1行で複数の例外をキャッチする

この記事では try/except 節について、特に一行で複数の例外をキャッチする方法と、 suppress() メソッドの使い方について見ていきます。

これらのテクニックは DRY (don’t repeat yourself) の原則に従った、よりアクセスしやすく汎用的なコードを書くのに役立ちます。

まず、問題から見ていきましょう。

try:
    do_the_thing()
except TypeError as e:
    do_the_other_thing()
except KeyError as e:
    do_the_other_thing()
except IndexError as e:
    do_the_other_thing()


残酷です。

見ての通り、これは非常にWETなコードで、同じ呼び出しを何度も繰り返しています。このようなプラクティスは、コードの読み込みやリファクタリングを悪夢のようなものにしてしまうのです。

例外処理を次々と書くよりも、これらの例外処理を一行にまとめた方がいいんじゃないですか?

複数の例外

手っ取り早く答えを知りたいのであれば、タプルを使うのが簡単です。

例外行タプルに含まれるすべてのエラーは、まとめて評価されます。

try:
    do_the_thing()
except (TypeError, KeyError, IndexError) as e:
    do_the_other_thing()


簡単でしょう?

バッドプラクティスを回避する

“エラーは黙って通過してはならない。” – Pythonの禅。

try/except句は、おそらくPythonで最も誤用されるパターンです。

不適切に使用すると、酔っ払いと街灯の決まり文句のようになってしまい、Pythonインタプリタが「クリスマスの12のエラー」を歌い始めたときだけ使われるようになります。

問題を解決するために、try とむき出しの例外を置くことはとても魅力的です。特に、致命的なエラーから回復したり、隠れたバグに光を当てたりする際に、例外はとても役に立ちますから。

そのため、except節を使用する際には、遭遇する可能性のあるエラーは指定し、そうでないものは除外するようにしましょう。

プログラムが失敗しても、問題が存在しないかのように装うよりは、問題ありません。

ということです。
エラーは決して黙って通過してはならない……明示的に沈黙させない限りは。

&gt

しかし、たまに例外処理を無視する機会があるときは、 suppress() を使用することができます。

from contextlib import suppress


with suppress(TypeError, KeyError, IndexError):
    do_the_thing()


suppress()` メソッドは、引数としていくつかの例外を受け取り、それらのエラーに対して try/except/pass を実行します。見ての通り、複数の例外を1行で記述することも可能です。

これにより、手動でtry/except/passを記述する手間を省くことができます。

try:
    do_the_thing()
except (TypeError, KeyError, IndexError) as e:
    pass


さらに、Python 3.4以上のバージョンで標準装備されています。

結論

この記事では、複数の例外を一行で処理する方法について説明しました。また、例外を無視する際のバッドプラクティスについて簡単に説明し、 supress() 関数を使って明示的に例外を抑制する方法を紹介しました。

タイトルとURLをコピーしました