Получить доступ

Что делают send, throw и yield from у генераторов?

MiddleИтераторы и генераторы
Ещё спрашивают так:
  • Как генераторы связаны с корутинами?
Коротко

Генератор — не только источник значений: 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 для композиции генераторов

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

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 и возвращаемое значение.
  • Связь с корутинами.

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем