※以下の企画です
今回は8章をやっていきます。
8章は「エラーと例外」というタイトルで、普段何気なくおまじない的に使っているtry/exeptあたりをちゃんと学べそうな気がしています。
それではやっていきますぅ。
8章 学習内容まとめ
そもそもエラーには2種類あり、構文エラーと例外とのこと。
本章はそれらをそれぞれ学べる内容になっていた。
例外の処理
例外を待ち構える文法は「try / except
」で書く。これはPythonに限らず様々な言語でサポートされている文法(try / catch
の方が個人的には馴染みがあるが)
特に新しい学びはないかなーと思って読んでいたが、except
はタプルで複数種類待ち構えられるというのは初めて知った。
>> except(RuntimeError,TypeError,NameError):
>> pass
また、try / except
はオプションでelse
をつけられる。
これはtry
で例外が発生しなかった場合にジャンプする場所となっていて、try
にコードをつらつら書くのではなくelse
句に書いていくことが推奨されていた。
try / except
で本来プロテクトしなくて良い例外までキャッチしてしまうのを防ぐためらしい。これはたしかにそう。
>> try:
>> print('try')
>> except:
>> print('except')
>> else:
>> print('else')
try
else
例外の送出
例外は意図的に送出もできる。これは自主的に使ったことが無かったものの、ちゃんと使えれば質の高いコードになるなと感じた。
方法は簡単でraise
を使うだけ。
>> raise NameError('oops')
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-2-41bcb0d57fce> in <cell line: 1>()
----> 1 raise NameError('oops')
NameError: oops
except
と組み合わせももちろん可能。
>> try:
>> raise NameError('oops!!!')
>> except NameError:
>> print('例外だああああ!')
>> raise
例外だああああ!
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-3-c755c7cd20cd> in <cell line: 1>()
1 try:
----> 2 raise NameError('oops!!!')
3 except NameError:
4 print('例外だああああ!')
5 raise
NameError: oops!!!
この場合、except
句内で引数なしのraise
を使用すると、現在処理中の例外(この場合は NameError)を再度発生させられる。
この仕様は本書だけだと読み取れなかったので、GPTに教えてもらった。
この処理を正しく使いこなせるかはわからないが、意識的に使えるよう脳に焼き付けておく…
クリーンアップ動作
try/except
構文には、else
意外に実はまだもう一つの文法がある(他にもあるかもだが、紹介されていたのはこれが最後)。
それがtry / excepyt / finally
。
finally
はtry
が例外を送出しようがしまいが関係なく実行される。
else
は「例外が発生しなかった場合に処理される」ものであったので、この違いに注意したい。
>> def divide(x,y):
>> try:
>> result = x / y
>> except ZeroDivisionError:
>> print("division by zero!")
>> else:
>> print("result is", result)
>> finally:
>> print("finally!")
上記のようなコードであれば、上手く割り算できようが、ゼロ除算が起きようが、他のエラー(文字列が入力されたとか)が起きようが、finally
句は実行される。
>> divide(1,2)
result is 0.5
finally!
>> divide(1,0)
division by zero!
finally!
>> divide("1","0")
finally!
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-5-598d3dd0ec63> in <cell line: 1>()
----> 1 divide("1","0")
<ipython-input-3-866838b2288c> in divide(x, y)
1 def divide(x,y):
2 try:
----> 3 result = x / y
4 except ZeroDivisionError:
5 print("division by zero!")
TypeError: unsupported operand type(s) for /: 'str' and 'str'
個人的には、大量のデータの書き出しとかに使えるんじゃないかなと思った。
ビッグデータの処理でCSVやらBigQueryやらに結果を格納していくときに、処理途中でエラー(想定外の無効な文字が入っていてとか)が生じた際に、finally
句でそこまでの結果を書き出しておくみたいな。
エラー用にexcept
句に書くよりもスマートに行けるんじゃないかなぁ。
これはぜひとも実務でも使ってみたい。
まとめ
僕の書くコードはエラーまみれの例外まみれなので、この章は非常に勉強になった。
特にfinally
はなんで今まで調べなかったのだろうと後悔しつつ、新たな学びになって良かったとも思う。
初心に戻る大切さを今更ながら痛感した…。
次回も楽しくやっていきます〜