Что такое генераторная функцияpython-77

Генераторная функция — это специальная функция, которая возвращает генератор (итератор) при своем вызове. Вместо использования return для возврата значения, она использует ключевое слово yield, что позволяет ей сохранять свое состояние между вызовами.

Ключевые особенности генераторных функций

  1. Ленивое выполнение (Lazy Evaluation) — код выполняется только при запросе следующего значения
  2. Сохранение состояния — функция "запоминает" место своего выполнения между вызовами
  3. Множественные точки выхода — может содержать несколько операторов yield
  4. Автоматическая реализация протокола итератора — не требует явного определения __iter__() и __next__()

Синтаксис генераторной функции

def generator_function(args):
    # Инициализация
    while condition:
        # Вычисления
        yield value  # Возврат значения и приостановка выполнения
    # Завершение работы

Как работает генераторная функция?

  1. Вызов функции возвращает объект-генератор, но не выполняет код функции сразу
  2. Первый next() запускает выполнение до первого yield
  3. Последующие next() продолжают выполнение с последнего yield
  4. Завершение происходит при достижении конца функции или return, вызывая StopIteration
def countdown(n):
    print("Starting countdown from", n)
    while n > 0:
        yield n
        n -= 1
    print("Countdown complete")

# Использование:
gen = countdown(3)
print(next(gen))  # Starting countdown from 3 \n 3
print(next(gen))  # 2
print(next(gen))  # 1
print(next(gen))  # Countdown complete \n StopIteration

Преимущества генераторных функций

  1. Экономия памяти — не нужно хранить всю последовательность
  2. Работа с бесконечными последовательностями
  3. Упрощение сложных итераторов
  4. Конвейерная обработка данных

Практические примеры

1. Чтение больших файлов

def read_large_file(file_path):
    with open(file_path) as f:
        for line in f:
            yield line.strip()  # Обрабатываем по одной строке

2. Генерация последовательностей

def fibonacci(limit=None):
    a, b = 0, 1
    count = 0
    while limit is None or count < limit:
        yield a
        a, b = b, a + b
        count += 1

3. Конвейер обработки данных

def data_pipeline(data):
    for item in data:
        processed = preprocess(item)
        if validate(processed):
            yield transform(processed)

Продвинутые возможности

1. Отправка данных в генератор

def accumulator():
    total = 0
    while True:
        value = yield total
        if value is None:
            break
        total += value

gen = accumulator()
next(gen)  # Инициализация
print(gen.send(10))  # 10
print(gen.send(20))  # 30

2. Возврат значения из генератора

def gen_with_return():
    yield 1
    yield 2
    return "Done"

g = gen_with_return()
print(next(g))  # 1
print(next(g))  # 2
try:
    next(g)
except StopIteration as e:
    print(e.value)  # "Done"

3. Делегирование генераторов

def chain_generators(*iterables):
    for it in iterables:
        yield from it  # Делегирует итерацию подгенератору

Резюмируем

Генераторная функция — это функция, которая при вызове возвращает объект-генератор. Она отличается от обычной функции использованием yield вместо return, что позволяет ей сохранять состояние между вызовами. Генераторные функции идеально подходят для работы с большими данными, создания конвейеров обработки и реализации сложных итерационных логик. Они автоматически реализуют протокол итератора, предоставляя мощный инструмент для ленивых вычислений.