Callable generators (PEP 288: Generator Attributes, again)
Greg Chapman
glc at well.com
Wed Nov 19 13:24:20 EST 2003
More information about the Python-list mailing list
Wed Nov 19 13:24:20 EST 2003
- Previous message (by thread): Callable generators (PEP 288: Generator Attributes, again)
- Next message (by thread): Callable generators (PEP 288: Generator Attributes, again)
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On 18 Nov 2003 02:11:48 -0800, francisgavila at yahoo.com (Francis Avila) wrote: >Personally, I'd like to one day be able to do stupid things like this: >>>> e = echo() >>>> tuple(feed(e, xrange(5)) >(0, 1, 2, 3, 4) Here's one way of getting a resumable function with parameters: def echo(defvalue = 1): def gen(): args = [None] def callgen(arg=defvalue): args[0] = arg return gennext() yield callgen while True: value, = args yield value gennext = gen().next return gennext() You can elaborate on this by abstracting out the generator caller (callgen) with something like the following (which also allows throwing an exception into a generator, provided the generator adheres to the convention of unpacking its arguments when resumed from a yield): class GenArgs(object): def __init__(self): self.args = () self.exc = None def __iter__(self): if self.exc: raise self.exc return iter(self.args) def __call__(self): if self.exc: raise self.exc return self.args class CallGen(object): def __init__(self, gen, genargs, numargs, defaults): assert numargs >= 0 and len(defaults) <= numargs self.gen = gen self.gennext = gen.next self.genargs = genargs self.numargs = numargs self.defaults = defaults def __call__(self, *cargs): numargs = self.numargs numcargs = len(cargs) if numcargs < numargs: diff = numargs-numcargs defaults = self.defaults if diff <= len(defaults): cargs = cargs+defaults[-diff:] numcargs = numargs if numargs != numcargs: raise TypeError('%s takes %d arguments (%d given)' % ( self.gen.gi_frame.f_code.co_name, numargs, numcargs )) self.genargs.args = cargs return self.gennext() def throw(self, exc): self.genargs.exc = exc try: return self.gennext() except StopIteration: return None def makeCallGen(gen, numargs, defaults=()): genargs = GenArgs() return CallGen(gen, genargs, numargs, defaults), genargs # Here's echo again with the above: def echo(defvalue=1): def gen(): while True: value, = args yield value callgen, args = makeCallGen(gen(), 1, (defvalue,)) return callgen --- Greg Chapman
- Previous message (by thread): Callable generators (PEP 288: Generator Attributes, again)
- Next message (by thread): Callable generators (PEP 288: Generator Attributes, again)
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Python-list mailing list