5.2.8 Yield expressions

##
5.2.8 Yield expressions

  yield_atom | ::= | "(" yield_expression ")"
  yield_expression | ::= | "yield" [expression_list]

  Download entire grammar as text.

New in version 2.5.

The `yield` expression is only used when defining a generator function, and can only be used in the body of a function definition. Using a `yield` expression in a function definition is sufficient to cause that definition to create a generator function instead of a normal function.

When a generator function is called, it returns an iterator known as a generator. That generator then controls the execution of a generator function. The execution starts when one of the generator's methods is called. At that time, the execution proceeds to the first `yield` expression, where it is suspended again, returning the value of expression_list to generator's caller. By suspended we mean that all local state is retained, including the current bindings of local variables, the instruction pointer, and the internal evaluation stack. When the execution is resumed by calling one of the generator's methods, the function can proceed exactly as if the `yield` expression was just another external call. The value of the `yield` expression after resuming depends on the method which resumed the execution.

All of this makes generator functions quite similar to coroutines; they yield multiple times, they have more than one entry point and their execution can be suspended. The only difference is that a generator function cannot control where should the execution continue after it yields; the control is always transfered to the generator's caller.

The following generator's methods can be used to control the execution of a generator function:

`next`( | )

  Starts the execution of a generator function or resumes it at the last executed `yield` expression. When a generator function is resumed with a `next()` method, the current `yield` expression always evaluates to `None`. The execution then continues to the next `yield` expression, where the generator is suspended again, and the value of the expression_list is returned to `next()`'s caller. If the generator exits without yielding another value, a `StopIteration` exception is raised.

`send`( | value)

  Resumes the execution and ``sends'' a value into the generator function. The `value` argument becomes the result of the current `yield` expression. The `send()` method returns the next value yielded by the generator, or raises `StopIteration` if the generator exits without yielding another value. When `send()` is called to start the generator, it must be called with `None` as the argument, because there is no `yield` expression that could receieve the value.

`throw`( | type[, value[, traceback]])

  Raises an exception of type `type` at the point where generator was paused, and returns the next value yielded by the generator function. If the generator exits without yielding another value, a `StopIteration` exception is raised. If the generator function does not catch the passed-in exception, or raises a different exception, then that exception propagates to the caller.

`close`( | )

  Raises a `GeneratorExit` at the point where the generator function was paused. If the generator function then raises `StopIteration` (by exiting normally, or due to already being closed) or `GeneratorExit` (by not catching the exception), close returns to its caller. If the generator yields a value, a `RuntimeError` is raised. If the generator raises any other exception, it is propagated to the caller. `close` does nothing if the generator has already exited due to an exception or normal exit.

Here is a simple example that demonstrates the behavior of generators and generator functions:

    >>> def echo(value=None):
    ...     print "Execution starts when 'next()' is called for the first time."
    ...     try:
    ...         while True:
    ...             try:
    ...                 value = (yield value)
    ...             except GeneratorExit:
    ...                 # never catch GeneratorExit
    ...                 raise
    ...             except Exception, e:
    ...                 value = e
    ...     finally:
    ...         print "Don't forget to clean up when 'close()' is called."
    ...
    >>> generator = echo(1)
    >>> print generator.next()
    Execution starts when 'next()' is called for the first time.
    1
    >>> print generator.next()
    None
    >>> print generator.send(2)
    2
    >>> generator.throw(TypeError, "spam")
    TypeError('spam',)
    >>> generator.close()
    Don't forget to clean up when 'close()' is called.

See Also:

PEP 0342, Coroutines via Enhanced Generators
  The proposal to enhance the API and syntax of generators, making them usable as simple coroutines.