知りたかったこと

  • try-catch の有効範囲はどれくらいなのか(呼び出した関数で起きたエラーも拾えるのか)
  • ネストしたエラーの扱いってどうするのが良いんだろう

結論

呼び出された先の例外もキャッチできますφ(・

調べて知ったこと

  • エラーには構文エラー例外がある
  • 複数の例外を指定することができる
except (RuntimeError, TypeError, NameError):
    pass
  • exceptは上から順に見て、引っかかったタイミングでそのexcept節内部のみを実行する
  • 最後の except 節では例外名を省いて、ワイルドカードにすることができる
    • しかし、ワイルドカードの except 節は通常のプログラムエラーをたやすく隠してしまうため、注意は必要
  • Try…exceptの中にはelse節を設けることができる。else節は全てのexcept節よりも後ろに置く
    • try 節で全く例外が創出されなかった時に実行されるコードを記述することができる
for arg in sys.argv[1:]:
    try:
        f = open(arg, 'r')
    except OSError:
        print('cannot open', arg)
    else:
        print(arg, 'has', len(f.readlines()), 'lines')
        f.close()

参考:
Python の例外処理(try, except, else, finally) | note.nkmk.me
8. エラーと例外 — Python 3.8.1 ドキュメント

  • Except 節では例外名の後に変数を指定できる。この変数は例外インスタンスに結び付けられ、instance.argsに例外インスタンス生成時の引数が入る。

    • 例外インスタンスに実装されている__str__instance.argsをわざわざ出力しなくても見られるようになっているので、print(inst)で見られる。便利。
  • 例外ハンドラは、try 節の直下で発生した例外を処理するだけではなく、その try 節から(たとえ間接的にでも)呼び出された関数の内部で発生した例外も処理する。(!)

def this_fails():
...     x = 1/0
...
>>> try:
...     this_fails()
... except ZeroDivisionError as err:
...     print('Handling run-time error:', err)
...
Handling run-time error: division by zero