Выглядят функции-генераторы также как и обычные, но содержат выражения с ключевым словом yield для последовательного генерирования значений, которые могут быть использованы в циклах for, либо их получения при помощи функции next.
На каждой yield работа функции временно приостанавливается, при этом сохраняется состояние исполнения, включая локальные переменные, указатель на текущую инструкцию, внутренний стек и состояние обработки исключения. При последующем обращении к итератору генератора функция продолжает своё исполнение с места, на котором была приостановлена. Этим функции-генераторы отличаются от обычных функций, при вызове которых исполнение всякий раз начинается с начала.
Если функция достигает инструкции return, либо конца, возбуждается исключение StopIteration и итератор исчерпывает себя.
def generator(): for item in ('first', 'second', 'third'): yield itemТеперь можно вызывать эту функцию и использовать функцию next.
gen = generator()value = next(gen)print(value)# Output: firstДостаточно часто, а точнее практически всегда, генераторы используют в циклах for. Преимущество такого подхода в том, что можно получить все возможные значения и не словить ошибку StopIteration.
for item in gen: print(item, end=' ')# Output: second thirdТеперь если вызвать функцию next еще раз, то получим то самое исключение.
next(gen)# Output:Traceback (most recent call last):File "main.py", line 12, in <module> next(gen)StopIteration