== Python generators ==
Python generators are available in Python 2.3 as a standard feature. While Python 2.2 required an additional line {{{from __future__ import generators}}} to be able to use them, Python 2.3 does not need any imports to be able to use generators. Pychecker works fine with generator syntax as well, so you can use generators right away without any problem.

The following is a brief player test which worked successfully on a dog. It converts the face lights into a dodgy christmas light display:

{{{
          # TestGenerator.py
          #
          # Experimenting with test generator
          import Global
          import IndicatorAction
          
          blink = None      # Our generator object
          
          def blink_lights():
             i = 0
             while 1:
                print "Generator is working!"
                pattern = [0,0,0,0,0]
                pattern[i] = 1
                IndicatorAction.showFacePattern(pattern)
                i = (i + 1) % 5
                yield 1

          def DecideNextAction():
              global blink
              Global.frameReset()
          
              if blink == None:
                  print "Creating generator..."
                  blink = blink_lights()   # Create the generator object
          
              print "Calling generator"
              blink.next()     # Call the generator object
}}}

Note: Unlike "return", "yield" requires a value to be passed to it, even if you don't use that value.

=== (Old proposal which used to be on the "Ideas" page) Using Python generators in behaviours ===
 * I hope this is the right area to place this...anyway, Python has a feature called "generators" which may be useful when implementing behaviours. They're basically functions which can be suspended and then resumed from the point of suspension. Suspending is achieved by the "yield" keyword, which can return a value. For example (ripped from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66316):
{{{
          
          # needs Python 2.2 or above!
          from __future__ import generators

          def fib():
              "unbounded generator, creates Fibonacci sequence"
              x = 0
              y = 1
              while 1:
                  x, y = y, x + y
                  yield x


          if __name__ == "__main__":
              g = fib()
              for i in range(9):
                  print g.next(),
}}}
 * Generators are available in Python 2.2 by adding "from __future__ import generators" to your python files. In Python 2.3 onwards, generators are built into Python without needing to import additional modules.
 * Documentation on generators is sparse, so here's a few links: [http://www.python.org/peps/pep-0255.html the proposal for generators (old, but still relevant)], [http://docs.python.org/tut/node11.html#SECTION00111000000000000000000 a brief mention in the python tutorial]
 * I believe generators will be useful when implementing the lower level skills such as kicks and grabs, where usually many variables (e.g. frames since the grab began) are needed to retain the current state of the action. These variables can be replaced with a generator function quite elegantly. You also have a choice whether you want to call the generator  or not, too - for example, you're performing a grab, but you see the ball in front of you (when it needs to be under your head), you can cancel the grab by not calling the generator function again.
 * As seen in the example above, the generator ("g", in this case) is actually a python object created from the function ("fib"). To "restart" the function just create a new generator from the function. Generator objects should be garbage collected, so there shouldn't be any trouble with discarding a generator which hasn't been run to completion.
 * It should be available on the dogs, unless this feature was somehow cut from the dogs' version of python.