[Python-ideas] Possible PEP 380 tweak (original) (raw)

Ron Adam rrr at ronadam.com
Sat Oct 30 18:54:15 CEST 2010


On 10/30/2010 02:58 AM, Nick Coghlan wrote:

On Sat, Oct 30, 2010 at 4:42 PM, Ron Adam<rrr at ronadam.com> wrote:

Ok, after thinking about this for a while, I think the "yield from" would be too limited if it could only be used for consumers that must run until the end. That rules out a whole lot of pipes, filters and other things that consume-some, emit-some, consume-somemore, and emit-somemore. Indeed, the "stop-in-the-middle" aspect is tricky, but is the crux of what we're struggling with here.

I think I figured out something that may be more flexible and insn't too complicated. Basically a way to use yield from, while declaring how to force the end of iteration? Interesting idea.

Not iteration, iteration can continue. It signals the end of delegation, and returns control to the generator that initiated the delegation.

However, I think sentinel values are likely a better way to handle this in a pure PEP 380 context.

Sentinel values aren't always better because they require a extra comparison on each item.

Here's an example. Modifying this example to use sentinel values rather than throwing in exceptions actually makes it all fairly straightforward in a PEP 380 context. So maybe the moral of this whole thread is really "sentinel values good, sentinel exceptions bad". # Helper function to finish off a generator by sending a sentinel value def finish(g, sentinel=None): try: g.send(sentinel) except StopIteration as ex: return ex.value def gtally(endtally=None): # Tallies numbers until sentinel is passed in count = tally = 0

value = object()

Left over from earlier edit?

while 1: value = yield if value is endtally: return count, tally count += 1 tally += value

The comparison is executed on every loop. A try-except would be outside the loop.

def gaverage(endavg=None): count, tally = (yield from gtally(endavg)) return tally / count

def main(): g = gaverage() next(g) for x in range(100): g.send(x) return finish(g)

Cheers, Ron



More information about the Python-ideas mailing list