dackdive's blog

新米webエンジニアによる技術ブログ。JavaScript(React), Salesforce, Python など

[python 2系]with構文 (__enter__と__exit__)

__enter____exit__ という見慣れないメソッドに触れる機会があったので、メモ。
python のバージョンは 2.7。

__enter__ と __exit__ の使い方

__enter____exit__ を実装したクラスは コンテキストマネージャ と呼ばれ、
with 構文(with ステートメント)と組み合わせて使う。

with 構文とはこのような形。

with Foo('foo') as f:
  print f.xxx()

with 文に入った時に __enter__ メソッドが呼ばれ、with 文を抜けるときに __exit__ メソッドが呼ばれる。

__enter____exit__ を実装したクラスのサンプルは以下のようになる。

実行結果
__init__
__enter__
hoge
None
None
None
__exit__

どんな時に使うのか

例としてよく挙げられているのは

with open('file.txt') as f:
  f.read()

のようなコード。with 文で書くと抜けるときに必ずファイルのクローズ (f.close()) が呼ばれる。
他には DB とのコネクションを切断する・レコードのロックを解除するなど、
ある処理の成否に関わらず最後に必ず行う必要のある処理__exit__ に書いてこの構文を使うとすっきり書ける。

また、1個クラスを作っておくと色々なところで再利用できるというのも利点。

公式ドキュメントにもこのように書いてますもんね。

with 文は、ブロックの実行を、コンテキストマネージャによって定義されたメソッドでラップするために使われます( with文とコンテキストマネージャ セクションを参照してください)。これにより、よくある try...except...finally 利用パターンをカプセル化して便利に再利用することができます。

http://docs.python.jp/2/reference/compound_stmts.html#with

リファレンス