mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 03:44:55 +00:00 
			
		
		
		
	svn+ssh://pythondev@svn.python.org/python/trunk ........ r73465 | nick.coghlan | 2009-06-17 22:12:15 +1000 (Wed, 17 Jun 2009) | 1 line Issue 6288: update the contextlib.nested() docs to explain why it has been deprecated and should generally be avoided ........
		
			
				
	
	
		
			136 lines
		
	
	
	
		
			5.3 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
			
		
		
	
	
			136 lines
		
	
	
	
		
			5.3 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
:mod:`contextlib` --- Utilities for :keyword:`with`\ -statement contexts
 | 
						|
========================================================================
 | 
						|
 | 
						|
.. module:: contextlib
 | 
						|
   :synopsis: Utilities for with-statement contexts.
 | 
						|
 | 
						|
 | 
						|
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:
 | 
						|
 | 
						|
 | 
						|
.. function:: contextmanager(func)
 | 
						|
 | 
						|
   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.
 | 
						|
 | 
						|
 | 
						|
.. function:: nested(mgr1[, mgr2[, ...]])
 | 
						|
 | 
						|
   Combine multiple context managers into a single nested context manager.
 | 
						|
 | 
						|
   This function has been deprecated in favour of the multiple manager form
 | 
						|
   of the :keyword:`with` statement.
 | 
						|
 | 
						|
   The one advantage of this function over the multiple manager form of the
 | 
						|
   :keyword:`with` statement is that argument unpacking allows it to be
 | 
						|
   used with a variable number of context managers as follows::
 | 
						|
 | 
						|
      from contextlib import nested
 | 
						|
 | 
						|
      with nested(*managers):
 | 
						|
          do_something()
 | 
						|
 | 
						|
   Note that if the :meth:`__exit__` method of one of the nested context managers
 | 
						|
   indicates an exception should be suppressed, no exception information will be
 | 
						|
   passed to any remaining outer context managers. Similarly, if the
 | 
						|
   :meth:`__exit__` method of one of the nested managers raises an exception, any
 | 
						|
   previous exception state will be lost; the new exception will be passed to the
 | 
						|
   :meth:`__exit__` methods of any remaining outer context managers. In general,
 | 
						|
   :meth:`__exit__` methods should avoid raising exceptions, and in particular they
 | 
						|
   should not re-raise a passed-in exception.
 | 
						|
 | 
						|
   This function has two major quirks that have led to it being deprecated. Firstly,
 | 
						|
   as the context managers are all constructed before the function is invoked, the
 | 
						|
   :meth:`__new__` and :meth:`__init__` methods of the inner context managers are
 | 
						|
   not actually covered by the scope of the outer context managers. That means, for
 | 
						|
   example, that using :func:`nested` to open two files is a programming error as the
 | 
						|
   first file will not be closed promptly if an exception is thrown when opening
 | 
						|
   the second file.
 | 
						|
 | 
						|
   Secondly, if the :meth:`__enter__` method of one of the inner context managers
 | 
						|
   raises an exception that is caught and suppressed by the :meth:`__exit__` method
 | 
						|
   of one of the outer context managers, this construct will raise
 | 
						|
   :exc:`RuntimeError` rather than skipping the body of the :keyword:`with`
 | 
						|
   statement.
 | 
						|
 | 
						|
   Developers that need to support nesting of a variable number of context managers
 | 
						|
   can either use the :mod:`warnings` module to suppress the DeprecationWarning
 | 
						|
   raised by this function or else use this function as a model for an application
 | 
						|
   specific implementation.
 | 
						|
 | 
						|
   .. deprecated:: 3.1
 | 
						|
      The with-statement now supports this functionality directly (without the
 | 
						|
      confusing error prone quirks).
 | 
						|
 | 
						|
 | 
						|
.. 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.
 | 
						|
 | 
						|
 | 
						|
.. seealso::
 | 
						|
 | 
						|
   :pep:`0343` - The "with" statement
 | 
						|
      The specification, background, and examples for the Python :keyword:`with`
 | 
						|
      statement.
 | 
						|
 |