LoginSignup
4
4

More than 5 years have passed since last update.

Pythonの例外処理は、オブジェクトの削除を伴う

Posted at

前書き

何の気なしにPythonのドキュメントを眺めていると、次のような記述があった。

try 文は、ひとまとめの文に対して、例外処理および/またはクリーンアップコードを指定します ...[中略]... 例外が as target を使って代入されたとき、それは except 節の終わりに消去されます。これはちょうど、以下のコード:

except E as N:
    foo

が、以下のコードに翻訳されたかのようなものです:

except E as N:
    try:
        foo
    finally:
        del N

引用元:Python 言語リファレンス » 複合文 » try 文太字は引用者。

試してみる

実際に試してみると、なるほど確かにeが削除されているのが分かる。

>>> try:
...     raise Exception('spam')
... except Exception as e:
...     print(e)
...
spam
>>> print(e)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'e' is not defined

一方、with文ではそのような挙動を見せないので、なんとも解し難い。

>>> with open(r'./spam.txt') as fin:
...     pass
...
>>> fin.read()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: I/O operation on closed file.

リソースのクローズを伴うので、同じように削除してくれた方が扱いやすいような...

ハマるとしたら

知っておいて得な挙動でもないが、ともすれば次のようなハマり方をするかもしれない。

>>> e = 42
>>> try:
...     raise Exception('spam')
... except Exception as e:
...     print(e)
...
spam
>>> print(e)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'e' is not defined

変数名を被らせた本人が悪いのは言うまでもないが、
勝手にオブジェクトが消されてしまうのは見落としがちなような気もする。

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4