Документация Python неофициальный перевод

asyncio-runner.md

128 строк · 12.2 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3/library/asyncio-runner.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# Исполнители89**Исходный код:** [Lib/asyncio/runners.py](https://python-all.ru/src/3.14/Lib/asyncio/runners.py)1011В этом разделе описываются высокоуровневые примитивы asyncio для выполнения асинхронного кода.1213Они построены поверх [цикла событий](https://python-all.ru/3/library/asyncio-eventloop.html#asyncio-event-loop) с целью упростить использование асинхронного кода в распространённых сценариях.1415[Запуск asyncio-программы](https://python-all.ru/3/library/asyncio-runner.html#running-an-asyncio-program) [Контекстный менеджер Runner](https://python-all.ru/3/library/asyncio-runner.html#runner-context-manager) [Обработка прерывания с клавиатуры](https://python-all.ru/3/library/asyncio-runner.html#handling-keyboard-interruption)1617## [Запуск программы asyncio](https://python-all.ru/3/library/asyncio-runner.html#id1)1819#### `asyncio.run(coro, *, debug=None, loop_factory=None)`2021Выполняет *coro* в цикле событий asyncio и возвращает результат.2223Аргументом может быть любой ожидаемый объект.2425Эта функция выполняет ожидаемый объект, управляя циклом событий asyncio, *завершая асинхронные генераторы* и закрывая исполнитель.2627Эту функцию нельзя вызывать, когда в том же потоке выполняется другой цикл событий asyncio.2829Если *debug* равен `True`, цикл событий будет работать в режиме отладки. `False` явно отключает режим отладки. `None` используется для соблюдения глобальных настроек [режима отладки](https://python-all.ru/3/library/asyncio-dev.html#asyncio-debug-mode).3031Если *loop\_factory* не равен `None`, то он используется для создания нового цикла событий; в противном случае используется [`asyncio.new_event_loop()`](https://python-all.ru/3/library/asyncio-eventloop.html#asyncio.new_event_loop). В конце цикл закрывается. Эту функцию следует использовать как главную точку входа в asyncio-программы, и в идеале она должна быть вызвана только один раз. Рекомендуется использовать *loop\_factory* для настройки цикла событий вместо политик. Передача [`asyncio.EventLoop`](https://python-all.ru/3/library/asyncio-eventloop.html#asyncio.EventLoop) позволяет запускать asyncio без системы политик.3233Исполнителю даётся тайм-аут в 5 минут для завершения. Если исполнитель не завершился за это время, выводится предупреждение и исполнитель закрывается.3435Пример:3637```python38async def main():39    await asyncio.sleep(1)40    print('hello')4142asyncio.run(main())43```4445Добавлено в версии 3.7.4647Изменено в версии 3.9: Обновлено для использования [`loop.shutdown_default_executor()`](https://python-all.ru/3/library/asyncio-eventloop.html#asyncio.loop.shutdown_default_executor).4849Изменено в версии 3.10: *debug* по умолчанию равен `None`, чтобы соблюдать глобальные настройки режима отладки.5051Изменено в версии 3.12: Добавлен параметр *loop\_factory*.5253Изменено в версии 3.14: *coro* может быть любым ожидаемым объектом.5455> **Примечание**56>57> Система политик `asyncio` устарела и будет удалена в Python 3.16; начиная с этой версии, для настройки цикла событий нужен явный *loop\_factory*.5859## [Контекстный менеджер Runner](https://python-all.ru/3/library/asyncio-runner.html#id2)6061#### `class asyncio.Runner(*, debug=None, loop_factory=None)`6263Контекстный менеджер, упрощающий *множественные* вызовы асинхронных функций в одном контексте.6465Иногда несколько асинхронных функций верхнего уровня нужно вызывать в одном [цикле событий](https://python-all.ru/3/library/asyncio-eventloop.html#asyncio-event-loop) и [`contextvars.Context`](https://python-all.ru/3/library/contextvars.html#contextvars.Context).6667Если *debug* равен `True`, цикл событий будет работать в режиме отладки. `False` явно отключает режим отладки. `None` используется для соблюдения глобальных настроек [режима отладки](https://python-all.ru/3/library/asyncio-dev.html#asyncio-debug-mode).6869*loop\_factory* может использоваться для переопределения создания цикла. Ответственность *loop\_factory* – установить созданный цикл как текущий. По умолчанию используется [`asyncio.new_event_loop()`](https://python-all.ru/3/library/asyncio-eventloop.html#asyncio.new_event_loop) и устанавливается как текущий цикл событий с помощью [`asyncio.set_event_loop()`](https://python-all.ru/3/library/asyncio-eventloop.html#asyncio.set_event_loop), если *loop\_factory* равен `None`.7071В принципе, пример [`asyncio.run()`](https://python-all.ru/3/library/asyncio-runner.html#asyncio.run) можно переписать с использованием runner:7273```python74async def main():75    await asyncio.sleep(1)76    print('hello')7778with asyncio.Runner() as runner:79    runner.run(main())80```8182Добавлено в версии 3.12.8384#### `run(coro, *, context=None)`8586Выполняет *coro* во встроенном цикле событий.8788Аргументом может быть любой ожидаемый объект.8990Если аргумент является корутиной, он оборачивается в задачу.9192Необязательный аргумент *context*, передаваемый только по ключу, позволяет указать пользовательский [`contextvars.Context`](https://python-all.ru/3/library/contextvars.html#contextvars.Context) для выполнения кода. Если context равен `None`, используется контекст runner по умолчанию.9394Возвращает результат ожидаемого объекта или возбуждает исключение.9596Эту функцию нельзя вызывать, когда в том же потоке выполняется другой цикл событий asyncio.9798Изменено в версии 3.14: *coro* может быть любым ожидаемым объектом.99100#### `close()`101102Закрывает runner.103104Завершает асинхронные генераторы, останавливает исполнитель по умолчанию, закрывает цикл событий и освобождает встроенный [`contextvars.Context`](https://python-all.ru/3/library/contextvars.html#contextvars.Context).105106#### `get_loop()`107108Возвращает цикл событий, связанный с экземпляром runner.109110> **Примечание**111>112> `Runner` использует стратегию ленивой инициализации: его конструктор не инициализирует нижележащие низкоуровневые структуры.113>114> Встроенные *цикл событий* и *контекст* создаются при входе в тело [`with`](https://python-all.ru/3/reference/compound_stmts.html#with) или при первом вызове [`run()`](https://python-all.ru/3/library/asyncio-runner.html#asyncio.run) или [`get_loop()`](https://python-all.ru/3/library/asyncio-runner.html#asyncio.Runner.get_loop).115116## [Обработка прерывания с клавиатуры](https://python-all.ru/3/library/asyncio-runner.html#id3)117118Добавлено в версии 3.12.119120Когда [`signal.SIGINT`](https://python-all.ru/3/library/signal.html#signal.SIGINT) возбуждается `Ctrl`-`C`, по умолчанию в главном потоке возбуждается исключение [`KeyboardInterrupt`](https://python-all.ru/3/library/exceptions.html#KeyboardInterrupt). Однако это не работает с [`asyncio`](https://python-all.ru/3/library/asyncio.html#module-asyncio), поскольку оно может прервать внутренние механизмы asyncio и привести к зависанию программы при завершении.121122Чтобы смягчить эту проблему, [`asyncio`](https://python-all.ru/3/library/asyncio.html#module-asyncio) обрабатывает [`signal.SIGINT`](https://python-all.ru/3/library/signal.html#signal.SIGINT) следующим образом:1231241. [`asyncio.Runner.run()`](https://python-all.ru/3/library/asyncio-runner.html#asyncio.Runner.run) устанавливает собственный обработчик [`signal.SIGINT`](https://python-all.ru/3/library/signal.html#signal.SIGINT) до выполнения любого пользовательского кода и удаляет его при выходе из функции.1252. [`Runner`](https://python-all.ru/3/library/asyncio-runner.html#asyncio.Runner) создаёт главную задачу для переданной корутины для её выполнения.1263. Когда [`signal.SIGINT`](https://python-all.ru/3/library/signal.html#signal.SIGINT) возбуждается `Ctrl`-`C`, пользовательский обработчик сигнала отменяет главную задачу вызовом [`asyncio.Task.cancel()`](https://python-all.ru/3/library/asyncio-task.html#asyncio.Task.cancel), что возбуждает [`asyncio.CancelledError`](https://python-all.ru/3/library/asyncio-exceptions.html#asyncio.CancelledError) внутри главной задачи. Это приводит к разворачиванию стека Python, блоки `try/except` и `try/finally` можно использовать для очистки ресурсов. После отмены главной задачи [`asyncio.Runner.run()`](https://python-all.ru/3/library/asyncio-runner.html#asyncio.Runner.run) возбуждает [`KeyboardInterrupt`](https://python-all.ru/3/library/exceptions.html#KeyboardInterrupt).1274. Пользователь может написать плотный цикл, который не может быть прерван с помощью [`asyncio.Task.cancel()`](https://python-all.ru/3/library/asyncio-task.html#asyncio.Task.cancel); в этом случае второе нажатие `Ctrl`-`C` немедленно возбуждает [`KeyboardInterrupt`](https://python-all.ru/3/library/exceptions.html#KeyboardInterrupt) без отмены главной задачи.128