Ответ 1
Внутри генератора выражения (выход 42) будут давать значение 42, но оно также возвращает значение, которое либо равно None, если вы используете next(generator)
или заданное значение, если используете generator.send(value)
.
Итак, как вы говорите, вы можете использовать промежуточное значение для получения того же поведения, а не потому, что это синтаксический сахар, а потому, что выражения yield буквально возвращают значение, которое вы его отправляете.
Вы также можете сделать что-то вроде
def my_generator():
return (yield (yield 42) + 10)
Если мы назовем это, используя последовательность вызовов:
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)
Сначала мы получаем результат 42, и генератор по существу приостановлен в состоянии, которое вы могли бы описать как: return (yield <Input will go here> + 10)
,
Если мы тогда назовем g.send(1)
, получим вывод 11. и теперь генератор находится в состоянии:
return <Input will go here>
, то отправка g.send(22)
приведет к выбросу StopIteration(22)
из-за того, как обратная обработка обрабатывается в генераторах.
Таким образом, вы никогда не добираетесь до третьего отправления из-за исключения.
Надеюсь, что в этом примере становится более очевидным, как yield
работает в генераторах и почему синтаксис return (yield something)
не является чем-то особенным или экзотичным и работает точно так, как вы ожидали.
Что касается буквального вопроса, когда вы это сделаете? Хорошо, когда когда-либо вы хотите что-то уступить, а затем позже возвратите StopIteration, эхо-сигнал ввода пользователя, отправленного генератору. Потому что это буквально то, что говорится в коде. Я ожидаю, что такое поведение очень редко требуется.