I think this decorator sould be included in itertools:
from functools import wraps
class ReIter(object): __slots__ = 'f', 'args', 'kwargs'
def __init__(self,f,args,kwargs): self.f = f self.args = args self.kwargs = kwargs def __iter__(self): return self.f(*self.args, **self.kwargs)
def reiter(f): @wraps(f) def _reiter(*args,**kwargs): return ReIter(f,args,kwargs) return _reiter
Using this you can iterate over the return value of a generator decorated with reiter as often as you like (and not just once):
@reiter def gen(x,y): for i in xrange(x): yield i*y
g = gen(5,3) for x in g: sys.stdout.write('%r\n' % x) sys.stdout.write('\n') for x in g: sys.stdout.write('%r\n' % x)
The difference to tee is that old values are not remembered but the generator is evaluated when __iter__() is called. This might come in handy when you implement methods like items(), values() and keys() in a custom dict implementation.
Or is there already such a thing and I missed it?
PS: Maybe it should be called regen/ReGen instead of reiter/ReIter? PPS: Funny thing, both "Reiter" and "Regen" are german words. Reiter = rider or tab; Regen = rain.