Генераторы в классах: yield внутри методов

Когда обычных методов класса недостаточно ⚡

Представь ситуацию: ты пишешь класс для обработки большого потока данных. Обычные методы с return возвращают всё сразу — но что если данных миллионы? Загружать их в память целиком неэффективно. Вот где на помощь приходят генераторы с yield внутри методов класса!

Генераторы в классах — это мощный инструмент, который позволяет:

  • Экономить память за счёт ленивых вычислений 🦥
  • Создавать последовательности "на лету" ✈️
  • Делать код чище и читабельнее 🧼

Основы: делаем метод-генератор 🏗️

Создать генератор в классе проще простого — достаточно использовать yield вместо return:

class DataProcessor:
    def __init__(self, data):
        self.data = data

    def process(self):
        for item in self.data:
            yield item * 2  # Обрабатываем элементы по одному!

processor = DataProcessor([1, 2, 3])
for result in processor.process():
    print(result)
# Вывод: 2, 4, 6

Ключевые моменты:

  • Метод process() теперь генератор (из-за yield)
  • При вызове он возвращает генератор, а не готовый список
  • Данные обрабатываются поэлементно по мере необходимости

Реальный пример: чтение больших файлов 📚

Давай рассмотрим практический пример с обработкой CSV-файлов:

import csv

class CSVReader:
    def __init__(self, filename):
        self.filename = filename

    def read_rows(self):
        with open(self.filename, 'r') as file:
            reader = csv.reader(file)
            for row in reader:
                yield row  # Постепенно читаем файл

# Использование:

data_reader = CSVReader('huge_dataset.csv')
for row in data_reader.read_rows():
    process_row(row)  # Обрабатываем каждую строку отдельно

Преимущества подхода:

  • Файл читается построчно, а не целиком 🎯
  • Потребление памяти постоянно, даже для огромных файлов 🐘
  • Можно прервать обработку в любой момент ⏸️

Состояние генератора в классах 🧭

Генераторы в методах прекрасно работают с атрибутами класса:

class Paginator:
    def __init__(self, items, per_page=10):
        self.items = items
        self.per_page = per_page

    def paginate(self):
        for i in range(0, len(self.items), self.per_page):
            yield self.items[i:i + self.per_page]

# Использование:
pages = Paginator(list(range(100)), 15)
for page in pages.paginate():
    print(f"Страница: {page}")

Здесь мы:

  • Используем атрибуты класса (items, per_page) внутри генератора
  • Сохраняем состояние между вызовами yield
  • Создаём удобный интерфейс для постраничного вывода

Комбинируем с другими методами класса 🎲

Генераторы отлично сочетаются с обычными методами:

class Fibonacci:
    def __init__(self, limit):
        self.limit = limit

    def generate(self):
        a, b = 0, 1
        for _ in range(self.limit):
            yield a
            a, b = b, a + b

    def sum(self):
        return sum(self.generate())  # Используем генератор внутри метода

fib = Fibonacci(10)
print(list(fib.generate()))  # [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
print(fib.sum())  # 88

Такой подход делает классы:

  • Гибкими: можно использовать генерацию и обычные методы
  • Эффективными: не храним всю последовательность в памяти
  • Удобными: разные способы работы с данными в одном месте

Когда стоит использовать yield в методах? 🤔

Генераторы в классах особенно полезны, когда:

  1. Работаешь с большими или бесконечными последовательностями 🌌
  2. Нужно экономить память (ленивые вычисления) 💾
  3. Хочешь сделать код более читаемым и декларативным 📖
  4. Работаешь с потоками данных или пошаговой обработкой 🏗️

Но помни: если тебе нужно сразу все результаты — возможно, обычный метод с return будет лучше.

Главное на практике 🎯

  1. Генераторы в методах создаются через yield
  2. Они сохраняют контекст класса и его атрибуты
  3. Отлично сочетаются с другими методами класса
  4. Идеальны для обработки больших данных

Теперь ты готов создавать эффективные и элегантные классы с генераторами! Попробуй применить этот подход в своём следующем проекте — результат тебя приятно удивит. 😊

Скрыть рекламу навсегда

📘 VK Видео — обучение без ограничений

Все уроки доступны без VPN, без блокировок и зависаний.

Можно смотреть с телефона, планшета или компьютера — в любое время.

▶️ Смотреть на VK Видео