Асинхронный ввод-вывод: aiohttp, asyncio, async for, async with

🔄 Асинхронность в Python: как это работает?

Асинхронный код позволяет выполнять операции ввода-вывода (I/O) без блокировки основного потока программы. В отличие от многопоточности, здесь используется один поток, переключающийся между задачами при простое (ожидании ответа от внешних ресурсов).

import asyncio

async def main():
    print("Привет")
    await asyncio.sleep(1)  # Не блокирует поток, а передаёт управление
    print("Мир")

asyncio.run(main())

🧩 Ключевые компоненты

async/await - основа асинхронности

  • async объявляет корутину (асинхронную функцию)
  • await приостанавливает выполнение, пока операция не завершится
async def fetch_data():
    print("Начинаем загрузку")
    await asyncio.sleep(2)  # Имитация долгого запроса
    return "Данные получены"

🚀 aiohttp для HTTP-запросов

Библиотека для асинхронных HTTP-запросов. Работает в 3-5 раз быстрее синхронных аналогов при массовых запросах!

import aiohttp

async def fetch_url(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            return await response.text()

🔄 async for и async with

Асинхронные контекстные менеджеры (async with)

Управляют ресурсами с поддержкой await в методах __aenter__/__aexit__.

async with aiohttp.ClientSession() as session:
    # Работаем с сессией
    pass  # Автоматическое закрытие

Асинхронные итераторы (async for)

Итерируются по асинхронным генераторам:

async for item in async_generator():
    print(item)  # Между итерациями можно await!

🧑‍💻 Реальный пример: параллельные запросы

Сравните синхронный и асинхронный подход:

import asyncio
import aiohttp

urls = ["https://python.org", "https://github.com", "https://example.com"]

async def fetch_all():
    async with aiohttp.ClientSession() as session:
        tasks = [session.get(url) for url in urls]
        responses = await asyncio.gather(*tasks)
        return [await r.text() for r in responses]

# Запускаем всё вместе!
asyncio.run(fetch_all())

⚡ Производительность: цифры говорят сами за себя

Метод Время 10 запросов
Синхронный ~5.2 сек
Асинхронный ~0.8 сек

🤔 Частые ошибки

  1. Забыть await
    python # Ошибка! async def oops(): asyncio.sleep(1) # Нет await!

  2. Смешивать sync и async код
    Нельзя вызывать асинхронные функции из синхронных без asyncio.run()

  3. Блокирующие вызовы в корутинах
    time.sleep() вместо asyncio.sleep() остановит всю event loop!


🛠 Практическое задание

Создайте асинхронный сканер веб-сайтов, который: 1. Получает список URL из файла 2. Проверяет статус каждого (200/404/500) 3. Сохраняет результаты в CSV

async def check_site(session, url):
    try:
        async with session.get(url) as resp:
            return url, resp.status
    except:
        return url, "ERROR"

📌 Важные выводы

  1. Асинхронность ≠ многопоточность — работает в одном потоке
  2. await — точка переключения задач
  3. aiohttp в 3-5x быстрее requests для множества запросов
  4. Контекстные менеджеры (async with) и итераторы (async for) — must have
Скрыть рекламу навсегда

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

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

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

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