### ナビゲーション

- 索引
- モジュール |
- 次へ |
- 前へ |
- Python v2.6.2 documentation »
- Python 標準ライブラリ »
- 28. Python ランタイムサービス »

# 28.6. `contextlib` — `with` -構文コンテキストのためのユーティリティ。

バージョン 2.5 で追加.

このモジュールは `with` 文を必要とする一般的なタスクのためのユーティリティを提供します。 詳しい情報は、 コンテキストマネージャ型 と with文とコンテキストマネージャ を参照してください。

用意されている関数:

`contextlib.``contextmanager`(func)

  この関数はデコレータ(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` 文のすぐ後につづく文から実行を再開します。

`contextlib.``nested`(mgr1[, mgr2[, ...]])

  複数のコンテキストマネージャを一つのネストされたコンテキストマネージャへ結合します。

  このようなコードは:

      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__()` メソッドが例外を送出することは避けるべきであり、 特に渡された例外を再送出すべきではありません。

`contextlib.``closing`(thing)

  ブロックの完了時に 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()` が呼ばれます。

参考

PEP 0343 - The “with” statement
  仕様、背景、および、Python `with` 文の例。

### ナビゲーション

- 索引
- モジュール |
- 次へ |
- 前へ |
- Python v2.6.2 documentation »
- Python 標準ライブラリ »
- 28. Python ランタイムサービス »