Метод generator.send в Python

Можете максимально простым языком объяснить, как работает generator.send() в Python. Смотрел много примеров, но так и не понял, как он работает, и где может быть полезен


Ответы (1 шт):

Автор решения: insolor

Генератор может не только отправлять данные наружу с помощью оператора yield, но и получать их извне - для этого через метод send нужно эти данные в генератор передать, а генератор эти данные данные из yield должен принять.

Простейший пример, просто посылаем значения в генератор, он их печатает:

def test():
    while True:
        x = yield
        print(x)


t = test()
next(t)  # вызов next нужен, чтобы генератор начал выполняться, и дошел до первого yield
t.send(111)
t.send(123)
t.send(456)
t.send(789)

Вывод:

111
123
456
789

Другой пример - посылаем в генератор значения, он возвращает накопленную сумму:

def test():
    s = 0
    while True:
        x = yield s
        s += x


t = test()
next(t)
print(t.send(111))
print(t.send(123))
print(t.send(456))
print(t.send(789))

Вывод:

111
234
690
1479

Подобное можно сделать и с помощью ООП (создаем объект, вызываем метод, который как-то изменяет состояние объекта и возвращает что-то в ответ), но это по сути просто другой способ реализации - "на функциях".

Я рассматриваю такие генераторы как некое подобие клиент-серверного взаимодействия внутри одной программы: мы посылаем запросы в генератор, он дает ответ.

С моей точки зрения полезность такого двустороннего генератора сомнительна, но знать про данную возможность желательно. В PEP 342 -- Coroutines via Enhanced Generators как пример использования упоминается возможность неблокирующего чтения данных (если я правильно понял), но это мне кажется неактуальным с тех пор как появился синтаксис async/await.

Несколько интересных ответов на ru.stackoveflow.com по этой теме:

→ Ссылка