Re: [Python-ideas] yield * (Re: Missing operator.call)
Nick Coghlan wrote:
One important question to ask yourself is whether the semantics you want may make more sense as a new generator method (as happened with the addition of send() and throw()) rather than as new syntax.
def f(): c = g() yield *c print c.result()
That turns one line into three and makes it impossible to embed it in an expression. It's a very poor substitute for what I have in mind.
In particular, the return value of 'yield *' would likely still by needed for send() in the case where the subgenerator has already terminated, so the only sensible destination for the sent value is the generator that invoked 'yield *'
The effect I'm after is the same as what would happen if the subgenerator were yielding directly to the caller of the outer generator. Since, except for the first send(), it's only possible to send() something to a generator when it's suspended in a yield, anything sent to the outer generator after the subgenerator terminates would have to appear as the return value of some later (ordinary) yield in the outer generator itself or another subgenerator. The full expansion, taking sends into account, of result = yield *g() would be something like _g = g() try: _v = yield _g.next() while 1: _v = yield _g.send(_v) except StopIteration, _e: result = _e.return_value I think I've got that right. While it may look like the last value assigned to _v gets lost, that's not actually the case, because the last next() or send() call before _g terminates never returns, raising StopIteration instead. (Here I'm assuming the return value is passed back as an argument to the StopIteration exception, something that I think got proposed at one point but never adopted. The return value could alternatively be attached to the generator-iterator itself.) -- Greg
participants (1)
-
Greg Ewing