| \section{\module{contextlib} --- |
| Utilities for \keyword{with}-statement contexts.} |
| |
| \declaremodule{standard}{contextlib} |
| \modulesynopsis{Utilities for \keyword{with}-statement contexts.} |
| |
| \versionadded{2.5} |
| |
| This module provides utilities for common tasks involving the |
| \keyword{with} statement. |
| |
| Functions provided: |
| |
| \begin{funcdesc}{contextmanager}{func} |
| This function is a decorator that can be used to define context managers |
| for use with the \keyword{with} statement, without needing to create a |
| class or separate \method{__enter__()} and \method{__exit__()} methods. |
| |
| A simple example: |
| |
| \begin{verbatim} |
| from __future__ import with_statement |
| from contextlib import contextmanager |
| |
| @contextmanager |
| def tag(name): |
| print "<%s>" % name |
| yield |
| print "</%s>" % name |
| |
| >>> with tag("h1"): |
| ... print "foo" |
| ... |
| <h1> |
| foo |
| </h1> |
| \end{verbatim} |
| |
| When called, the decorated function must return a generator-iterator. |
| This iterator must yield exactly one value, which will be bound to the |
| targets in the \keyword{with} statement's \keyword{as} clause, if any. |
| |
| At the point where the generator yields, the block nested in the |
| \keyword{with} statement is executed. The generator is then resumed |
| after the block is exited. If an unhandled exception occurs in the |
| block, it is reraised inside the generator at the point where the yield |
| occurred. Thus, you can use a |
| \keyword{try}...\keyword{except}...\keyword{finally} statement to trap |
| the error (if any), or ensure that some cleanup takes place. |
| |
| Note that you can use \code{@contextmanager} to define a context |
| manager's \method{__context__} method. This is usually more convenient |
| than creating another class just to serve as a context. For example: |
| |
| \begin{verbatim} |
| from __future__ import with_statement |
| from contextlib import contextmanager |
| |
| class Tag: |
| def __init__(self, name): |
| self.name = name |
| |
| @contextmanager |
| def __context__(self): |
| print "<%s>" % self.name |
| yield self |
| print "</%s>" % self.name |
| |
| h1 = Tag("h1") |
| |
| >>> with h1 as me: |
| ... print "hello from", me |
| <h1> |
| hello from <__main__.Tag instance at 0x402ce8ec> |
| </h1> |
| \end{verbatim} |
| \end{funcdesc} |
| |
| \begin{funcdesc}{nested}{ctx1\optional{, ctx2\optional{, ...}}} |
| Combine multiple context managers into a single nested context manager. |
| |
| Code like this: |
| |
| \begin{verbatim} |
| from contextlib import nested |
| |
| with nested(A, B, C) as (X, Y, Z): |
| do_something() |
| \end{verbatim} |
| |
| is equivalent to this: |
| |
| \begin{verbatim} |
| with A as X: |
| with B as Y: |
| with C as Z: |
| do_something() |
| \end{verbatim} |
| |
| Note that if one of the nested contexts' \method{__exit__()} method |
| raises an exception, any previous exception state will be lost; the new |
| exception will be passed to the outer contexts' \method{__exit__()} |
| method(s), if any. In general, \method{__exit__()} methods should avoid |
| raising exceptions, and in particular they should not re-raise a |
| passed-in exception. |
| \end{funcdesc} |
| |
| \label{context-closing} |
| \begin{funcdesc}{closing}{thing} |
| Return a context manager that closes \var{thing} upon completion of the |
| block. This is basically equivalent to: |
| |
| \begin{verbatim} |
| from contextlib import contextmanager |
| |
| @contextmanager |
| def closing(thing): |
| try: |
| yield thing |
| finally: |
| thing.close() |
| \end{verbatim} |
| |
| And lets you write code like this: |
| \begin{verbatim} |
| from __future__ import with_statement |
| from contextlib import closing |
| import codecs |
| |
| with closing(codecs.open("foo", encoding="utf8")) as f: |
| for line in f: |
| print line.encode("latin1") |
| \end{verbatim} |
| |
| without needing to explicitly close \code{f}. Even if an error occurs, |
| \code{f.close()} will be called when the \keyword{with} block is exited. |
| |
| \end{funcdesc} |
| |
| \begin{seealso} |
| \seepep{0343}{The "with" statement} |
| {The specification, background, and examples for the |
| Python \keyword{with} statement.} |
| \end{seealso} |