Inside a generator the expressions (yield 42) will yield the value 42, but it also returns a value which is either None, if you use next(generator)
or a given value if you use generator.send(value)
.
So as you say, you could use an intermediate value to get the same behavior, not because this is syntactical sugar, but because the yield expressions is literally returning the value you send it.
You could equally do something like
def my_generator():
return (yield (yield 42) + 10)
If we call this, using the sequence of calls:
g = my_generator()
print(next(g))
try:
print('first response:', g.send(1))
print('Second response:', g.send(22))
print('third response:', g.send(3))
except StopIteration as e:
print('stopped at', e.value)
First we get the output of 42, and the generator is essentially paused in a state you could describe like: return (yield <Input will go here> + 10)
,
If we then call g.send(1)
we get the output 11. and the generator is now in the state:
return <Input will go here>
, then sending g.send(22)
will throw a StopIteration(22)
, because of the way return is handled in generators.
So you never get to the third send because of the exception.
I hope this example makes it a bit more apparent how yield
works in generators and why the syntax return (yield something)
is nothing special or exotic and works exactly how you'd expect it.
As for the literal question, when would you do this? Well when ever you want to yield something, and then later return a StopIteration echoing the input of the user sent to the generator. Because this is literally what the code is stating. I expect that such behavior is very rarely wanted.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…