Spec-Zone.ru › Python 3.14

Запускатели

Исходный код: Lib/asyncio/runners.py

В этом разделе описаны высокоуровневые примитивы asyncio для запуска кода asyncio.

Они построены на основе цикла событий и предназначены для упрощения использования асинхронного кода в распространённых сценариях.

  • Запуск программы asyncio
  • Менеджер контекста Runner
  • Обработка прерывания с клавиатуры

Запуск программы asyncio

asyncio.run(coro, *, debug=None, loop_factory=None)

Выполняет coro в цикле событий asyncio и возвращает результат.

Аргументом может быть любой объект, поддерживающий ожидание.

Эта функция запускает объект, поддерживающий ожидание, управляет циклом событий asyncio, завершает асинхронные генераторы и закрывает исполнитель.

Эту функцию нельзя вызывать, если в том же потоке уже работает другой цикл событий asyncio.

Если debug имеет значение True, цикл событий будет запущен в режиме отладки. False явно отключает режим отладки. None используется, чтобы учитывать глобальные настройки режима отладки.

Если loop_factory не равен None, он используется для создания нового цикла событий; в противном случае используется asyncio.new_event_loop(). Цикл закрывается по завершении. Эту функцию следует использовать в качестве основной точки входа в программы asyncio и в идеале вызывать только один раз. Для настройки цикла событий рекомендуется использовать loop_factory, а не политики. Передача asyncio.EventLoop позволяет запускать asyncio без системы политик.

Исполнителю даётся 5 минут на завершение работы. Если за это время он не завершит работу, будет выдано предупреждение, и исполнитель будет закрыт.

Пример:

async def main():
    await asyncio.sleep(1)
    print('hello')

asyncio.run(main())

Добавлено в версии 3.7.

Изменено в версии 3.9: Обновлено для использования loop.shutdown_default_executor().

Изменено в версии 3.10: По умолчанию debug имеет значение None, чтобы учитывать глобальные настройки режима отладки.

Изменено в версии 3.12: Добавлен параметр loop_factory.

Изменено в версии 3.14: coro может быть любым объектом, поддерживающим ожидание.

Примечание

Система политик asyncio объявлена устаревшей и будет удалена в Python 3.16; после этого для настройки цикла событий потребуется явно указать loop_factory.

Менеджер контекста Runner

class asyncio.Runner(*, debug=None, loop_factory=None)

Менеджер контекста, упрощающий выполнение нескольких асинхронных вызовов функций в одном контексте.

Иногда несколько асинхронных функций верхнего уровня нужно вызвать в одном и том же цикле событий и contextvars.Context.

Если debug имеет значение True, цикл событий будет запущен в режиме отладки. False явно отключает режим отладки. None используется, чтобы учитывать глобальные настройки режима отладки.

Параметр loop_factory можно использовать для переопределения создания цикла. Обязанность установить созданный цикл в качестве текущего лежит на loop_factory. По умолчанию используется asyncio.new_event_loop(), а если loop_factory имеет значение None, он устанавливается в качестве текущего цикла событий с помощью asyncio.set_event_loop().

Пример с asyncio.run() можно переписать, используя runner:

async def main():
    await asyncio.sleep(1)
    print('hello')

with asyncio.Runner() as runner:
    runner.run(main())

Добавлено в версии 3.11.

run(coro, *, context=None)

Выполняет coro во встроенном цикле событий.

Аргументом может быть любой объект, поддерживающий ожидание.

Если аргумент является сопрограммой, она оборачивается в Task.

Необязательный именованный аргумент context позволяет указать пользовательский contextvars.Context, в котором будет выполняться код. Если значение context равно None, используется контекст runner по умолчанию.

Возвращает результат объекта, поддерживающего ожидание, или вызывает исключение.

Эту функцию нельзя вызывать, если в том же потоке уже работает другой цикл событий asyncio.

Изменено в версии 3.14: coro может быть любым объектом, поддерживающим ожидание.

close()

Закрывает runner.

Завершает асинхронные генераторы, останавливает исполнитель по умолчанию, закрывает цикл событий и освобождает встроенный contextvars.Context.

get_loop()

Возвращает цикл событий, связанный с экземпляром runner.

Примечание

Runner использует стратегию отложенной инициализации: его конструктор не инициализирует нижележащие низкоуровневые структуры.

Встроенные loop и context создаются при входе в тело with или при первом вызове run() или get_loop().

Обработка прерывания с клавиатуры

Добавлено в версии 3.11.

Когда при нажатии Ctrl-C возникает signal.SIGINT, в главном потоке по умолчанию вызывается исключение KeyboardInterrupt. Однако с asyncio это не работает, поскольку может прервать внутренние механизмы asyncio и помешать завершению программы.

Чтобы смягчить эту проблему, asyncio обрабатывает signal.SIGINT следующим образом:

  1. asyncio.Runner.run() устанавливает пользовательский обработчик signal.SIGINT до выполнения любого пользовательского кода и удаляет его при выходе из функции.
  2. Runner создаёт для выполнения корутины главный Task.
  3. Когда при нажатии Ctrl-C возникает signal.SIGINT, пользовательский обработчик сигнала отменяет главный Task, вызывая asyncio.Task.cancel(), что вызывает asyncio.CancelledError внутри главного Task. В результате стек Python раскручивается; для очистки ресурсов можно использовать блоки try/except и try/finally. После отмены главного Task asyncio.Runner.run() вызывает KeyboardInterrupt.
  4. Пользователь может написать бесконечный цикл, который нельзя прервать с помощью asyncio.Task.cancel(); в таком случае повторное нажатие Ctrl-C немедленно вызывает KeyboardInterrupt, не отменяя главный Task.

© 2001 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.14/library/asyncio-runner.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API