草
pythonはやばい。理解に苦しむ挙動が多くてつらい。たとえば以下のコード
def inverse(a): if a == 0: raise ValueError('0で割ることはできません') return 1 / a def main(): e = 0 try: e = inverse(2) except ValueError as e: print(e.args[0]) print(e) main()
これは何と出力されるでしょうか?
0.5
となります。これは問題ありません
ではmainをこうするとどうでしょう
def main(): e = 0 try: e = inverse(0) except ValueError as e: print(e.args[0]) print(e)
inverse(0)
が例外を投げるので、以下のように出力されると予想するのではないでしょうか
0で割ることはできません 0
違います、実際はこうなります
0で割ることはできません Traceback (most recent call last): File "/Users/hisanori/hoge.py", line 17, in <module> main() File "/Users/hisanori/hoge.py", line 15, in main print(e) ^ UnboundLocalError: cannot access local variable 'e' where it is not associated with a value
未定義のローカル変数エラーが発生しました。関数内で定義したローカル変数と同じ名前の変数を例外ハンドラに使用し、実際に例外がスローされた場合、元のローカル変数の定義がなかった事にされてしまっています。例外発生時だけこんなエラーを出すなら例外が発生していない時も同じエラーにしてほしい・・・
JavaやJSなどでは例外ハンドラで新しいスコープが作られるので元のeと例外ハンドラのeは別の変数となり予想通りエラーメッセージと0が出力されます。Rubyの場合は例外ハンドラが新しいスコープを作らないらしくエラーメッセージが2回でます。
という感じに他の言語で培った常識が通じなかったりして、pythonにはあまり深入りしたくないという気持ちが強い