← Назад к вопросам
Что такое Task в asyncio?
2.0 Middle🔥 141 комментариев
#Python Core#Асинхронность и многопоточность
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Task в asyncio — Асинхронное выполнение корутин
Task — это объект, который оборачивает корутину и управляет её асинхронным выполнением в event loop. Это основной способ запуска нескольких корутин параллельно.
Зачем нужны Task'и
Сама по себе корутина — это просто объект с инструкциями. Чтобы её выполнить, нужно:
- Создать event loop
- Запустить корутину в loop'е
- Управлять её жизненным циклом
Task автоматизирует этот процесс:
import asyncio
async def fetch_data(url):
print(f'Загружаю {url}')
await asyncio.sleep(2)
return f'Данные от {url}'
# ❌ Плохо: корутина не выполняется
coro = fetch_data('https://api.example.com')
print(coro) # <coroutine object fetch_data at 0x...>
# ✅ Хорошо: Task выполняет корутину
async def main():
task = asyncio.create_task(fetch_data('https://api.example.com'))
result = await task
print(result) # Данные от https://api.example.com
asyncio.run(main())
Создание Task
1. asyncio.create_task() — Рекомендуемый способ
async def main():
# Создаёшь task и сразу начинает выполняться
task = asyncio.create_task(fetch_data('url1'))
# Пока task выполняется в фоне, ты можешь делать другое
print('Task запущена')
# Когда тебе нужен результат, ждёшь
result = await task
print(result)
asyncio.run(main())
2. asyncio.ensure_future() — Старый способ (не используй)
task = asyncio.ensure_future(fetch_data('url'))
3. Прямой await — Последовательно
async def main():
result = await fetch_data('url')
# Ждёшь, пока завершится перед тем, как продолжить
Параллельное выполнение с Task'ами
Основное преимущество Task'ов — можно запустить несколько параллельно:
import asyncio
import time
async def fetch(url, delay):
print(f'Начинаю загружать {url}')
await asyncio.sleep(delay)
print(f'Завершил {url}')
return f'Данные {url}'
async def main():
start = time.time()
# Создаём 3 task'и
task1 = asyncio.create_task(fetch('url1', 2))
task2 = asyncio.create_task(fetch('url2', 2))
task3 = asyncio.create_task(fetch('url3', 2))
# Ждём все три параллельно (2 сек, не 6)
results = await asyncio.gather(task1, task2, task3)
elapsed = time.time() - start
print(f'Заняло {elapsed:.1f} сек')
print(results)
asyncio.run(main())
# Output:
# Начинаю загружать url1
# Начинаю загружать url2
# Начинаю загружать url3
# Завершил url1
# Завершил url2
# Завершил url3
# Заняло 2.0 сек
asyncio.gather() vs asyncio.wait()
gather() — Простой способ
# Жди все task'и
results = await asyncio.gather(task1, task2, task3)
# Со скрытием ошибок
results = await asyncio.gather(
task1, task2, task3,
return_exceptions=True
)
wait() — Больше контроля
done, pending = await asyncio.wait(
[task1, task2, task3],
return_when=asyncio.FIRST_COMPLETED # Вернуть как только одна завершится
)
for task in done:
print(task.result())
Состояния Task'и
task = asyncio.create_task(fetch_data('url'))
print(task.done()) # False — ещё выполняется
# ... ждём ...
print(task.done()) # True — завершена
if task.done():
print(task.result()) # Результат
# или
try:
print(task.exception()) # Если была ошибка
except:
pass
Отмена Task'и
async def long_operation():
try:
for i in range(10):
print(i)
await asyncio.sleep(1)
except asyncio.CancelledError:
print('Task была отменена')
raise
async def main():
task = asyncio.create_task(long_operation())
await asyncio.sleep(3)
task.cancel() # Отмени task
try:
await task
except asyncio.CancelledError:
print('Task отменена и ошибка обработана')
asyncio.run(main())
Практический пример: Веб-краулер
import asyncio
import aiohttp
async def fetch_url(session, url):
async with session.get(url) as response:
return await response.text()
async def crawl_urls(urls):
tasks = []
async with aiohttp.ClientSession() as session:
for url in urls:
task = asyncio.create_task(fetch_url(session, url))
tasks.append(task)
# Загружай все параллельно
results = await asyncio.gather(*tasks)
return results
url_list = ['https://example.com', 'https://google.com', 'https://github.com']
results = asyncio.run(crawl_urls(url_list))
На интервью
Ответи так:
"Task — это обёртка вокруг корутины, которая запускает её в event loop и управляет жизненным циклом. Основное назначение — запускать несколько корутин параллельно с помощью asyncio.create_task(). Task можно отменить, получить результат, или обработать исключения. Это ключевое понятие asyncio."