Generators and their next() and send() methods

Thomas Mlynarczyk thomas at mlynarczyk-webdesign.de
Sun Nov 16 22:36:07 CET 2008


Arnaud Delobelle schrieb:

> If you want to simply 'set' the generator (by which I take you mean
> 'change its state') without without iterating it one step, then what you
> need is a class with an __iter__() method.  Then you can change the
> state of the object between calls to next().  E.g.

>>>> class MyGenerator(object):
> ...     def __init__(self, v): self.v = v
> ...     def __iter__(self):
> ...         for x in range(10):
> ...             yield self.v
> ... 
>>>> g = MyGenerator(5)
>>>> for i in g:
> ...     g.v = input("val:")
> ...     print i

That's a good idea, thanks! Meanwhile I have succeeded in writing a 
decorator which allows an argument for next():

def myway( g ):
     class mygen( object ):
         def __init__( self, n ):
             self.g = g( n )
         def __iter__( self ):
             return self
         def next( self, s = None ):
             return self.g.next() if s is None else self.g.send( s )
         def send( self, s ):
             return self.g.send( s )
     return mygen

@myway
def gen( n ):
     i = 0
     while i <= n:
         s = yield i
         if s is not None:
             i = s
         else:
             i += 1

Of course, this is just an exercise -- it doesn't look as if it's worth 
using @mayway in any "real" code just to be able to write g.next(42) 
instead of g.send(42). Still, I would like to know why it was decided to 
introduce a send() method instead of allowing an argument for next().

Thanks and greetings,
Thomas


-- 
Ce n'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!
(Coluche)



More information about the Python-list mailing list