Короткий ответ
Корутина — функция, которая умеет приостанавливать выполнение в точке ожидания и возобновлять его позже. Объявляется через async def, а запускается через await из другой корутины или через asyncio.run().
Как это работает подробнее
Современные корутины развились из генераторов с yield, а синтаксис async/await появился в Python 3.5.
- Приостановка. await «замораживает» корутину до готовности ожидаемой операции, а управление в это время получает цикл событий.
- Запуск. При вызове корутина возвращает объект корутины, поэтому выполнить её код можно только через цикл событий.
- Происхождение. Исторически корутины выросли из генераторов, поддерживающих yield.
- Применение. Корутины уместны там, где много ожидания ввода-вывода: сетевые запросы, чтение файлов, обращения к базам данных и API.
Пример кода
Корутина с ожиданием
import asyncio
async def fetch_data():
await asyncio.sleep(1)
return 'Data fetched'Что использовать на практике
- Конкурентный запуск. Объединяй несколько корутин через asyncio.gather() для параллельных запросов.
- Структура. Дроби асинхронную логику на небольшие корутины с понятными именами.
- Ожидание результата. Всегда либо ожидай корутину через await, либо передавай её в asyncio.run().
Подводные камни
- Невыполненный код. Простой вызов корутины без await или asyncio.run() не запустит её тело.
- Смешение механизмов. yield-генераторы и async-корутины устроены по-разному, их нельзя смешивать напрямую.
- Сложность отладки. Переключения между корутинами усложняют чтение и трассировку ошибок.
Как отвечать на собеседовании
- Дай определение: функция, умеющая приостанавливаться и возобновляться → опиши путь от yield-генераторов к async/await → объясни, как await передаёт управление циклу событий → приведи пример и подчеркни, что корутина выполняется только через цикл событий.