mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 18:07:37 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			166 lines
		
	
	
	
		
			5 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
			
		
		
	
	
			166 lines
		
	
	
	
		
			5 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
| :mod:`contextlib` --- Utilities for :keyword:`with`\ -statement contexts
 | |
| ========================================================================
 | |
| 
 | |
| .. module:: contextlib
 | |
|    :synopsis: Utilities for with-statement contexts.
 | |
| 
 | |
| **Source code:** :source:`Lib/contextlib.py`
 | |
| 
 | |
| --------------
 | |
| 
 | |
| This module provides utilities for common tasks involving the :keyword:`with`
 | |
| statement. For more information see also :ref:`typecontextmanager` and
 | |
| :ref:`context-managers`.
 | |
| 
 | |
| Functions provided:
 | |
| 
 | |
| 
 | |
| .. decorator:: contextmanager
 | |
| 
 | |
|    This function is a :term:`decorator` that can be used to define a factory
 | |
|    function for :keyword:`with` statement context managers, without needing to
 | |
|    create a class or separate :meth:`__enter__` and :meth:`__exit__` methods.
 | |
| 
 | |
|    A simple example (this is not recommended as a real way of generating HTML!)::
 | |
| 
 | |
|       from contextlib import contextmanager
 | |
| 
 | |
|       @contextmanager
 | |
|       def tag(name):
 | |
|           print("<%s>" % name)
 | |
|           yield
 | |
|           print("</%s>" % name)
 | |
| 
 | |
|       >>> with tag("h1"):
 | |
|       ...    print("foo")
 | |
|       ...
 | |
|       <h1>
 | |
|       foo
 | |
|       </h1>
 | |
| 
 | |
|    The function being decorated must return a :term:`generator`-iterator when
 | |
|    called. 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. If an exception is
 | |
|    trapped merely in order to log it or to perform some action (rather than to
 | |
|    suppress it entirely), the generator must reraise that exception. Otherwise the
 | |
|    generator context manager will indicate to the :keyword:`with` statement that
 | |
|    the exception has been handled, and execution will resume with the statement
 | |
|    immediately following the :keyword:`with` statement.
 | |
| 
 | |
|    contextmanager uses :class:`ContextDecorator` so the context managers it
 | |
|    creates can be used as decorators as well as in :keyword:`with` statements.
 | |
| 
 | |
|    .. versionchanged:: 3.2
 | |
|       Use of :class:`ContextDecorator`.
 | |
| 
 | |
| 
 | |
| .. function:: closing(thing)
 | |
| 
 | |
|    Return a context manager that closes *thing* upon completion of the block.  This
 | |
|    is basically equivalent to::
 | |
| 
 | |
|       from contextlib import contextmanager
 | |
| 
 | |
|       @contextmanager
 | |
|       def closing(thing):
 | |
|           try:
 | |
|               yield thing
 | |
|           finally:
 | |
|               thing.close()
 | |
| 
 | |
|    And lets you write code like this::
 | |
| 
 | |
|       from contextlib import closing
 | |
|       from urllib.request import urlopen
 | |
| 
 | |
|       with closing(urlopen('http://www.python.org')) as page:
 | |
|           for line in page:
 | |
|               print(line)
 | |
| 
 | |
|    without needing to explicitly close ``page``.  Even if an error occurs,
 | |
|    ``page.close()`` will be called when the :keyword:`with` block is exited.
 | |
| 
 | |
| 
 | |
| .. class:: ContextDecorator()
 | |
| 
 | |
|    A base class that enables a context manager to also be used as a decorator.
 | |
| 
 | |
|    Context managers inheriting from ``ContextDecorator`` have to implement
 | |
|    ``__enter__`` and ``__exit__`` as normal. ``__exit__`` retains its optional
 | |
|    exception handling even when used as a decorator.
 | |
| 
 | |
|    ``ContextDecorator`` is used by :func:`contextmanager`, so you get this
 | |
|    functionality automatically.
 | |
| 
 | |
|    Example of ``ContextDecorator``::
 | |
| 
 | |
|       from contextlib import ContextDecorator
 | |
| 
 | |
|       class mycontext(ContextDecorator):
 | |
|           def __enter__(self):
 | |
|               print('Starting')
 | |
|               return self
 | |
| 
 | |
|           def __exit__(self, *exc):
 | |
|               print('Finishing')
 | |
|               return False
 | |
| 
 | |
|       >>> @mycontext()
 | |
|       ... def function():
 | |
|       ...     print('The bit in the middle')
 | |
|       ...
 | |
|       >>> function()
 | |
|       Starting
 | |
|       The bit in the middle
 | |
|       Finishing
 | |
| 
 | |
|       >>> with mycontext():
 | |
|       ...     print('The bit in the middle')
 | |
|       ...
 | |
|       Starting
 | |
|       The bit in the middle
 | |
|       Finishing
 | |
| 
 | |
|    This change is just syntactic sugar for any construct of the following form::
 | |
| 
 | |
|       def f():
 | |
|           with cm():
 | |
|               # Do stuff
 | |
| 
 | |
|    ``ContextDecorator`` lets you instead write::
 | |
| 
 | |
|       @cm()
 | |
|       def f():
 | |
|           # Do stuff
 | |
| 
 | |
|    It makes it clear that the ``cm`` applies to the whole function, rather than
 | |
|    just a piece of it (and saving an indentation level is nice, too).
 | |
| 
 | |
|    Existing context managers that already have a base class can be extended by
 | |
|    using ``ContextDecorator`` as a mixin class::
 | |
| 
 | |
|       from contextlib import ContextDecorator
 | |
| 
 | |
|       class mycontext(ContextBaseClass, ContextDecorator):
 | |
|           def __enter__(self):
 | |
|               return self
 | |
| 
 | |
|           def __exit__(self, *exc):
 | |
|               return False
 | |
| 
 | |
|    .. versionadded:: 3.2
 | |
| 
 | |
| 
 | |
| .. seealso::
 | |
| 
 | |
|    :pep:`0343` - The "with" statement
 | |
|       The specification, background, and examples for the Python :keyword:`with`
 | |
|       statement.
 | |
| 
 |