10.1 AsyncIterator

Асинхронні ітератори (AsyncIterator) дозволяють працювати з послідовностями даних, які виробляють елементи асинхронно. Вони використовуються в асинхронних функціях та корутинах для ітерації по даних, які можуть бути отримані з затримкою, наприклад, з мережевих запитів, асинхронних операцій введення-виведення або інших асинхронних джерел.

Асинхронний ітератор

Асинхронний ітератор повинен реалізовувати два методи:

Метод __aiter__():

Цей метод повинен повертати сам асинхронний ітератор. Він аналогічний методу __iter__() для синхронних ітераторів.

Метод __anext__():

Цей метод повинен повертати наступне значення асинхронно або викликати виключення StopAsyncIteration, якщо елементи закінчились. Він аналогічний методу __next__() для синхронних ітераторів.

Приклад:


import asyncio

class AsyncIterator:
    def __init__(self, start, end):
        self.current = start
        self.end = end
        
    def __aiter__(self):
        return self
        
    async def __anext__(self)(self):
        if self.current >= self.end:
            raise StopAsyncIteration
        
        await asyncio.sleep(1)  # Імітація асинхронної затримки
        self.current += 1
        return self.current
        
async def main():
    async for number in AsyncIterator(1, 5):
        print(number)
        
asyncio.run(main())

Асинхронні ітератори дозволяють обробляти дані по мірі їх надходження, не блокуючи виконання інших завдань. Це особливо корисно для роботи з мережевими запитами та іншими асинхронними операціями.

Використання асинхронних ітераторів дозволяє писати більш читабельний та підтримуваний код для обробки послідовностей даних асинхронно.

10.2 AsyncGenerator

Асинхронні генератори дозволяють виробляти значення асинхронно, використовуючи ключові слова async та await. Вони працюють аналогічно звичайним генераторам, але можуть призупиняти виконання для виконання асинхронних операцій.

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

Асинхронний генератор визначається з використанням async def та yield. Асинхронні генератори можуть використовувати await всередині себе для виконання асинхронних операцій.

Приклад:


async def async_generator():
    for i in range(3):
        await asyncio.sleep(1)  # Асинхронна затримка
        yield i  # Генерація значення

Використання асинхронного генератора

Асинхронні генератори використовуються всередині асинхронних функцій з допомогою оператора async for.


import asyncio

async def main():
    async for value in async_generator():
        print(value)
            
asyncio.run(main())

Асинхронні генератори покращують читабельність та підтримуваність коду, дозволяючи використовувати просту синтаксичну конструкцію async for для роботи з асинхронними послідовностями.