mirror of https://github.com/python/cpython
Document the contextlib module.
This commit is contained in:
parent
849974fb56
commit
d207b4f376
|
@ -371,6 +371,7 @@ and how to embed it in other applications.
|
|||
\input{libbltin} % really __builtin__
|
||||
\input{libmain} % really __main__
|
||||
\input{libwarnings}
|
||||
\input{libcontextlib}
|
||||
\input{libatexit}
|
||||
\input{libtraceback}
|
||||
\input{libfuture} % really __future__
|
||||
|
|
|
@ -0,0 +1,140 @@
|
|||
\section{\module{contextlib} ---
|
||||
Utilities for \keyword{with}-statement contexts.}
|
||||
|
||||
\declaremodule{standard}{contextlib}
|
||||
\modulesynopsis{Utilities for \keyword{with}-statement contexts.}
|
||||
|
||||
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 contextlib import closing
|
||||
|
||||
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}
|
Loading…
Reference in New Issue