Асинхронный ввод-вывод: 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 сек |
🤔 Частые ошибки
-
Забыть
await
python # Ошибка! async def oops(): asyncio.sleep(1) # Нет await! -
Смешивать sync и async код
Нельзя вызывать асинхронные функции из синхронных безasyncio.run() -
Блокирующие вызовы в корутинах
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"
📌 Важные выводы
- Асинхронность ≠ многопоточность — работает в одном потоке
await— точка переключения задачaiohttpв 3-5x быстрееrequestsдля множества запросов- Контекстные менеджеры (
async with) и итераторы (async for) — must have