Короткий ответ
send(value) передаёт значение внутрь генератора, которое становится результатом текущего выражения yield, и продолжает выполнение до следующего yield — это превращает генератор в двусторонний канал обмена данными.
Как это работает подробнее
Первый вызов должен быть next(gen) или send(None), чтобы довести выполнение до первого yield — только после этого send(value) имеет смысл. Переданное значение становится результатом выражения x = yield ... в точке приостановки.
Пример кода
example-261.py
def accumulator():
total = 0
while True:
value = yield total
total += value
acc = accumulator()
print(next(acc)) # 0 - доводим до первого yield
print(acc.send(10)) # 10 - total=10, возвращён до следующего yield
print(acc.send(5)) # 15Что использовать на практике
- Практика.
send()используют для реализации сопрограмм — конвейеров обработки данных, где внешний код управляет темпом и содержимым подаваемых данных, или простых накопителей состояния. В современном коде для асинхронной конкурентности предпочитаютasync/await, аsend()на «классических» генераторах остаётся нишевым инструментом.
Подводные камни
- Риски. Вызывают
send()как первую операцию на свежесозданном генераторе без предварительногоnext()— получаютTypeError, так как выполнение ещё не достиглоyield; не оборачивают работу с генератором вtry/except StopIteration, где это нужно для аккуратного завершения конвейера.