The return value of a Python generator function is an iterator. With this little wrapper it becomes an iterable object so you can iterate through its items more than once.
>>> from __future__ import generators
>>> def f(n):
... for i in xrange(n):
... yield i*10
...
>>> x=f(10)
>>> list(x)
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> list(x)
[]
>>>
>>> f = regen(f)
>>>
>>> x = f(10)
>>> list(x)
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> list(x)
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>>
Note: regen works nicely with the new Python @decorator syntax:
@regen def f(n): ...