Что делают send, throw и yield from у генераторов?
- Как генераторы связаны с корутинами?
Генератор — не только источник значений: send(x) передаёт значение внутрь (оно становится результатом выражения yield), throw(exc) бросает исключение в точке yield, close() завершает. yield from делегирует подгенератору: пробрасывает значения, send и throw, а возвращает его return.
- Первый send — только send(None) или next(): генератор ещё не дошёл до yield
- Return в генераторе — StopIteration.value
- На этих механизмах исторически построен asyncio (до async/await)
А ещё Сейчас send используют редко — в основном yield from для композиции генераторов
Подробно
send превращает генератор в сопрограмму с состоянием: накопители, конечные автоматы, парсеры, которым данные подаются порциями.
yield from (PEP 380) решает две задачи: короткая запись for x in sub: yield x и прозрачная передача send, throw и возвращаемого значения между вызывающим и подгенератором.
Связь с async/await. До Python 3.5 корутины asyncio были генераторами с yield from; цикл событий двигал их через send. Нативные корутины async def — отдельный тип, но устроены по той же схеме: await — аналог yield from, приостанавливающий выполнение до готовности.
Пример
def averager():
total = count = 0
avg = None
while True:
x = yield avg
total += x; count += 1
avg = total / count
g = averager(); next(g)
g.send(10) # 10.0
g.send(20) # 15.0
def flatten(items):
for x in items:
if isinstance(x, list):
yield from flatten(x)
else:
yield xЧто хотят услышать
- send, throw, close.
- yield from и возвращаемое значение.
- Связь с корутинами.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗yield from только перебирает значения подгенератора: send в него не попадает, а return в генераторе запрещён
- ✗Первым вызовом можно отправить send(42)
- ✓send(x) делает x результатом yield; yield from делегирует подгенератору и возвращает его return
- ✗throw завершает генератор, не возбуждая исключения внутри
Разбор темы
- Итераторы, генераторы и itertools
Протокол итерации, генераторы и генераторные выражения, срезы, send и yield from, ленивые инструменты itertools.
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.