Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #5584 > unrolled thread

Re: in search of graceful co-routines

Started byIan Kelly <ian.g.kelly@gmail.com>
First post2011-05-17 11:26 -0600
Last post2011-05-17 11:26 -0600
Articles 1 — 1 participant

Back to article view | Back to comp.lang.python

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: in search of graceful co-routines Ian Kelly <ian.g.kelly@gmail.com> - 2011-05-17 11:26 -0600

#5584 — Re: in search of graceful co-routines

FromIan Kelly <ian.g.kelly@gmail.com>
Date2011-05-17 11:26 -0600
SubjectRe: in search of graceful co-routines
Message-ID<mailman.1682.1305653245.9059.python-list@python.org>
On Tue, May 17, 2011 at 11:04 AM, Chris Withers <chris@simplistix.co.uk> wrote:
> Now, since the sequence is long, and comes from a file, I wanted the
> provider to be an iterator, so it occurred to me I could try and use the new
> 2-way generator communication to solve the "communicate back with the
> provider", with something like:
>
> for item in provider:
>  try:
>    consumer.handleItem(self)
>  except:
>     provider.send('fail')
>  else:
>     provider.send('succeed')
>
> ..but of course, this won't work, as 'send' causes the provider iteration to
> continue and then returns a value itself. That feels weird and wrong to me,
> but I guess my use case might not be what was intended for the send method.
>
> Anyway, I wonder how other people would write this?
> (I'm particularly interested in a sane way to use the two way communication
> that PEP 342 introduced)

You can use send the way you're wanting to.  It will look something like this:

def provider():
  result = None
  while True:
    if result is None:
      if has_more_items():
        next_item = get_next_item()
      else:
        break
    elif result == 'fail':
      process_fail()
      next_item = None
    elif result == 'succeed':
      process_succeed()
      next_item = None
    else:
      raise ValueError('unknown result %s' % result)
    result = (yield next_item)

Whenever you call provider().next() or provider().send(None), you
simply get the next item.  If you call provider().send('succeed') or
provider().send('fail'), then the corresponding code is run and the
yielded value is None, without consuming anything from the sequence.

Cheers,
Ian

[toc] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web