バージョン 2.5 で追加.
このモジュールは with 文を必要とする一般的なタスクのためのユーティリティを提供します。 詳しい情報は、 コンテキストマネージャ型 と with文とコンテキストマネージャ を参照してください。
用意されている関数:
この関数はデコレータ(decorator)であり、 with 文コンテキストマネージャのためのファクトリ関数の定義に利用できます。 ファクトリ関数を定義するために、クラスあるいは別の __enter__() と __exit__() メソッドを作る必要はありません。
簡単な例(実際にHTMLを生成する方法としてはお勧めできません!):
from contextlib import contextmanager
@contextmanager
def tag(name):
print "<%s>" % name
yield
print "</%s>" % name
>>> with tag("h1"):
... print "foo"
...
<h1>
foo
</h1>
デコレートされた関数は呼び出されたときにジェネレータ(generator)-イテレータを返します。このイテレータは値をちょうど一つyieldしなければなりません。 with 文の as 節が存在するなら、その値がas節のターゲットへ束縛されることになります。
ジェネレータがyieldするところで、 with 文のネストされたブロックが実行されます。 ジェネレータはブロックから出た後に再開されます。ブロック内で処理されない例外が発生した場合は、 yieldが起きた場所でジェネレータ内部へ再送出されます。 このように、(もしあれば)エラーを捕捉したり、後片付け処理を確実に実行したりするために、 try...except...finally 文を使うことができます。 単に例外のログをとるためだけに、もしくは(完全に例外を抑えてしまうのではなく) あるアクションを実行するだけに例外を捕まえるなら、ジェネレータはその例外を再送出しなければなりません。 そうしないと、ジェネレータコンテキストマネージャは例外が処理された with 文を指しており、 その with 文のすぐ後につづく文から実行を再開します。
複数のコンテキストマネージャを一つのネストされたコンテキストマネージャへ結合します。
このようなコードは:
from contextlib import nested
with nested(A(), B(), C()) as (X, Y, Z):
do_something()
これと同等です:
m1, m2, m3 = A(), B(), C()
with m1 as X:
with m2 as Y:
with m3 as Z:
do_something()
ネストされたコンテキストマネージャの一つの __exit__() メソッドに止めるべき例外がある場合は、残りの外側のコンテキストマネージャすべてに 例外情報が渡されないということに注意してください。同じように、ネストされたマネージャの一つの __exit__() メソッドが 例外を送出したならば、どんな以前の例外状態も失われ、新しい例外が残りすべての外側にあるコンテキストマネージャの __exit__() メソッドに渡されます。一般的に __exit__() メソッドが例外を送出することは避けるべきであり、 特に渡された例外を再送出すべきではありません。
ブロックの完了時に thing を閉じるコンテキストマネージャを返します。これは基本的に以下と等価です:
from contextlib import contextmanager
@contextmanager
def closing(thing):
try:
yield thing
finally:
thing.close()
そして、明確に page を閉じる必要なしに、このように書くことができます:
from contextlib import closing
import urllib
with closing(urllib.urlopen('http://www.python.org')) as page:
for line in page:
print line
たとえエラーが発生したとしても、 with ブロックを出るときに page.close() が呼ばれます。