← Назад к вопросам

Что значит вызвать генератор?

2.7 Senior🔥 251 комментариев
#DevOps и инфраструктура#Django

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Генераторы в Python

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

Как работает вызов генератора

Когда ты вызываешь функцию с yield, она не выполняется сразу. Вместо этого возвращается объект генератора:

def my_generator():
    print("Начало")
    yield 1
    print("После первого yield")
    yield 2
    print("После второго yield")
    yield 3

# Вызов генератора НЕ выполняет код, а только создаёт объект
gen = my_generator()
print(gen)  # <generator object my_generator at 0x...>

Фактический код выполняется лениво — только когда ты запрашиваешь значения.

Итерирование по генератору

gen = my_generator()

# Способ 1: через next()
print(next(gen))  # "Начало" → 1
print(next(gen))  # "После первого yield" → 2
print(next(gen))  # "После второго yield" → 3
# next(gen)  # StopIteration — конец

# Способ 2: через цикл for (удобнее)
gen = my_generator()
for value in gen:
    print(value)  # 1, 2, 3

Преимущества генераторов

1. Экономия памяти Вместо создания списка всех значений, генератор выдаёт их поодиночке:

# Плохо: список из миллиона чисел в памяти
def get_numbers():
    return [i for i in range(1000000)]

# Хорошо: числа генерируются по мере надобности
def get_numbers_gen():
    for i in range(1000000):
        yield i

result1 = get_numbers()  # ~ 8 MB в памяти
result2 = get_numbers_gen()  # ~ 0 KB (объект генератора)

2. Лентивое вычисление Вычисления начинаются только когда нужны значения:

def process_large_file(filename):
    with open(filename) as f:
        for line in f:
            yield line.strip()

# Файл читается построчно, не весь сразу
for line in process_large_file(huge.txt):
    print(line)

3. Бесконечные последовательности Можешь создавать потоки значений без конца:

def infinite_counter():
    count = 0
    while True:
        yield count
        count += 1

counter = infinite_counter()
print(next(counter))  # 0
print(next(counter))  # 1
print(next(counter))  # 2

Выражения-генераторы

Они похожи на list comprehension, но экономят память:

# List comprehension (создаёт список)
list_nums = [x*2 for x in range(5)]  # [0, 2, 4, 6, 8]

# Generator expression (создаёт генератор)
gen_nums = (x*2 for x in range(5))
print(next(gen_nums))  # 0
print(next(gen_nums))  # 2

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

def fibonacci():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

fib = fibonacci()
for i in range(10):
    print(next(fib), end=" ")  # 0 1 1 2 3 5 8 13 21 34

Отправка значений в генератор

Генератор может получать данные через send():

def echo():
    while True:
        x = yield
        if x is not None:
            print(f"Получено: {x}")

gen = echo()
next(gen)  # Инициализация
gen.send("Привет")  # Получено: Привет
gen.send(42)  # Получено: 42

Резюме

Вызов генератора — это создание объекта-итератора, который:

  • Не выполняет код функции сразу
  • Запоминает состояние между вызовами next()
  • Генерирует значения лениво, по требованию
  • Позволяет работать с бесконечными или очень большими последовательностями эффективно

Это мощный инструмент для оптимизации памяти и создания элегантного, функционального кода.

Что значит вызвать генератор? | PrepBro