Generators and their next() and send() methods

Aaron Brady castironpi at gmail.com
Mon Nov 17 03:27:50 CET 2008


On Nov 16, 3:36 pm, Thomas Mlynarczyk <tho... at mlynarczyk-webdesign.de>
wrote:
> 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():

Here's a different structure if you want it.  Untested.

def myway( g ):
  def init( *ar, **kw ):
     g= g( *ar, **kw )
     class mygen( object ):
         def __iter__( self ):
             return self
         def next( self, s= None ):
             return g.next() if s is None else g.send( s )
         def send( self, s ):
             return g.send( s )
     return mygen
  return init

And, if you don't intend to use 'myway' on 'listiterator's and such,
'send( None )' is equivalent to 'next( )'.

def myway( g ):
  def init( *ar, **kw ):
     g= g( *ar, **kw )
     class mygen( object ):
         def __iter__( self ):
             return self
         def next( self, s= None ):
             return g.send( s )
         def send( self, s ):
             return g.send( s )
     return mygen
  return init

There's probably a typo in it.



More information about the Python-list mailing list