asyncio-task.md
1> **Источник:** https://python-all.ru/3.9/library/asyncio-task.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# Корутины и задачи89В этом разделе представлены высокоуровневые API asyncio для работы с корутинами и задачами.1011- [Корутины](https://python-all.ru/3.9/library/asyncio-task.html#coroutines)12- [Ожидаемые объекты](https://python-all.ru/3.9/library/asyncio-task.html#awaitables)13- [Запуск asyncio-программы](https://python-all.ru/3.9/library/asyncio-task.html#running-an-asyncio-program)14- [Создание задач](https://python-all.ru/3.9/library/asyncio-task.html#creating-tasks)15- [Приостановка выполнения](https://python-all.ru/3.9/library/asyncio-task.html#sleeping)16- [Одновременное выполнение задач](https://python-all.ru/3.9/library/asyncio-task.html#running-tasks-concurrently)17- [Защита от отмены](https://python-all.ru/3.9/library/asyncio-task.html#shielding-from-cancellation)18- [Тайм-ауты](https://python-all.ru/3.9/library/asyncio-task.html#timeouts)19- [Примитивы ожидания](https://python-all.ru/3.9/library/asyncio-task.html#waiting-primitives)20- [Выполнение в потоках](https://python-all.ru/3.9/library/asyncio-task.html#running-in-threads)21- [Планирование из других потоков](https://python-all.ru/3.9/library/asyncio-task.html#scheduling-from-other-threads)22- [Интроспекция](https://python-all.ru/3.9/library/asyncio-task.html#introspection)23- [Объект задачи](https://python-all.ru/3.9/library/asyncio-task.html#task-object)24- [Корутины на основе генераторов](https://python-all.ru/3.9/library/asyncio-task.html#generator-based-coroutines)2526## [Корутины](https://python-all.ru/3.9/library/asyncio-task.html#id1)2728[Корутины](https://python-all.ru/3.9/glossary.html#term-coroutine), объявленные с помощью синтаксиса async/await, являются предпочтительным способом написания приложений asyncio. Например, следующий фрагмент кода выводит «hello», ждёт 1 секунду, а затем выводит «world»:2930```python31>>> import asyncio3233>>> async def main():34... print('hello')35... await asyncio.sleep(1)36... print('world')3738>>> asyncio.run(main())39hello40world41```4243Обратите внимание, что простой вызов корутины не запланирует её выполнение:4445```python46>>> main()47<coroutine object main at 0x1053bb7c8>48```4950Для фактического запуска корутины asyncio предоставляет три основных механизма:5152- Функция [`asyncio.run()`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.run) для запуска точки входа верхнего уровня – функции «main()» (см. пример выше.)53- Ожидание корутины. Следующий фрагмент кода выведет «hello» после ожидания в 1 секунду, а затем выведет «world» после ожидания *ещё* 2 секунд:5455 ```python56 import asyncio57 import time5859 async def say_after(delay, what):60 await asyncio.sleep(delay)61 print(what)6263 async def main():64 print(f"started at {time.strftime('%X')}")6566 await say_after(1, 'hello')67 await say_after(2, 'world')6869 print(f"finished at {time.strftime('%X')}")7071 asyncio.run(main())72 ```7374 Ожидаемый вывод:7576 ```python77 started at 17:13:5278 hello79 world80 finished at 17:13:5581 ```82- Функция [`asyncio.create_task()`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.create_task) для параллельного запуска корутин в качестве asyncio [`Tasks`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.Task).8384 Давайте изменим пример выше и запустим две `say_after` корутины *параллельно*:8586 ```python87 async def main():88 task1 = asyncio.create_task(89 say_after(1, 'hello'))9091 task2 = asyncio.create_task(92 say_after(2, 'world'))9394 print(f"started at {time.strftime('%X')}")9596 # Ожидать завершения обеих задач (должно занять97 # около 2 секунд).98 await task199 await task2100101 print(f"finished at {time.strftime('%X')}")102 ```103104 Обратите внимание, что ожидаемый вывод теперь показывает, что фрагмент выполняется на 1 секунду быстрее, чем раньше:105106 ```python107 started at 17:14:32108 hello109 world110 finished at 17:14:34111 ```112113## [Ожидаемые объекты](https://python-all.ru/3.9/library/asyncio-task.html#id2)114115Говорят, что объект является **ожидаемым** объектом, если его можно использовать в выражении [`await`](https://python-all.ru/3.9/reference/expressions.html#await). Многие API asyncio предназначены для принятия ожидаемых объектов.116117Существует три основных типа *ожидаемых* объектов: **корутины**, **задачи** и **future**.118119Корутины120121Корутины Python являются *ожидаемыми объектами*, а значит, их можно ожидать из других корутин:122123```python124import asyncio125126async def nested():127 return 42128129async def main():130 # Если просто вызвать "nested()", ничего не произойдет.131 # Создается объект корутины, но он не ожидается,132 # поэтому он *вообще не выполнится*.133 nested()134135 # Давайте поступим иначе и теперь ожидаем его:136 print(await nested()) # выведет "42".137138asyncio.run(main())139```140141> **Важно**142>143> В данной документации термин «корутина» может использоваться для двух тесно связанных понятий:144>145> - *корутинная функция*: функция [`async def`](https://python-all.ru/3.9/reference/compound_stmts.html#async-def);146> - *объект корутины*: объект, возвращаемый при вызове *корутинной функции*.147148asyncio также поддерживает устаревшие [корутины на основе генераторов](https://python-all.ru/3.9/library/asyncio-task.html#asyncio-generator-based-coro).149150Задачи151152*Задачи* используются для планирования корутин *параллельно*.153154Когда корутина обёрнута в *задачу* с помощью таких функций, как [`asyncio.create_task()`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.create_task), корутина автоматически планируется к скорому выполнению:155156```python157import asyncio158159async def nested():160 return 42161162async def main():163 # Запланировать выполнение nested() вскоре конкурентно164 # с "main()".165 task = asyncio.create_task(nested())166167 # "задача" теперь можно использовать для отмены "nested()" или168 # можно просто применить await, чтобы дождаться завершения:169 await task170171asyncio.run(main())172```173174Future175176[`Future`](https://python-all.ru/3.9/library/asyncio-future.html#asyncio.Future) – это специальный **низкоуровневый** ожидаемый объект, который представляет **конечный результат** асинхронной операции.177178Когда объект Future *ожидается*, это означает, что корутина будет ожидать, пока Future не будет разрешён в каком-то другом месте.179180Объекты Future в asyncio необходимы для того, чтобы код, основанный на колбэках, мог использоваться с async/await.181182Обычно **нет необходимости** создавать объекты Future в коде уровня приложения.183184Объекты Future, иногда предоставляемые библиотеками и некоторыми API asyncio, можно ожидать (await):185186```python187async def main():188 await function_that_returns_a_future_object()189190 # это также допустимо:191 await asyncio.gather(192 function_that_returns_a_future_object(),193 some_python_coroutine()194 )195```196197Хороший пример низкоуровневой функции, возвращающей объект Future – [`loop.run_in_executor()`](https://python-all.ru/3.9/library/asyncio-eventloop.html#asyncio.loop.run_in_executor).198199## [Запуск программы asyncio](https://python-all.ru/3.9/library/asyncio-task.html#id3)200201#### `asyncio.run(coro, *, debug=False)`202203Выполняет [корутину](https://python-all.ru/3.9/glossary.html#term-coroutine) *coro* и возвращает результат.204205Эта функция выполняет переданную корутину, беря на себя управление циклом событий asyncio, *завершение асинхронных генераторов* и закрытие пула потоков.206207Эту функцию нельзя вызывать, когда в том же потоке выполняется другой цикл событий asyncio.208209Если *debug* равно `True`, цикл событий будет запущен в режиме отладки.210211Эта функция всегда создаёт новый цикл событий и закрывает его в конце. Её следует использовать в качестве главной точки входа для программ asyncio, и в идеале она должна вызываться только один раз.212213Пример:214215```python216async def main():217 await asyncio.sleep(1)218 print('hello')219220asyncio.run(main())221```222223Добавлено в версии 3.7.224225Изменено в версии 3.9: Обновлено для использования [`loop.shutdown_default_executor()`](https://python-all.ru/3.9/library/asyncio-eventloop.html#asyncio.loop.shutdown_default_executor).226227> **Примечание**228>229> Исходный код `asyncio.run()` можно найти в\\n[Lib/asyncio/runners.py](https://python-all.ru/src/3.9/Lib/asyncio/runners.py).230231## [Создание задач](https://python-all.ru/3.9/library/asyncio-task.html#id4)232233#### `asyncio.create_task(coro, *, name=None)`234235Wrap the *coro* [coroutine](https://python-all.ru/3.9/library/asyncio-task.html#coroutine) into a [`Task`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.Task) and schedule its execution. Return the Task object.236237Если *name* не равен `None`, он устанавливается как имя задачи с помощью [`Task.set_name()`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.Task.set_name).238239Задача выполняется в цикле, возвращаемом [`get_running_loop()`](https://python-all.ru/3.9/library/asyncio-eventloop.html#asyncio.get_running_loop); [`RuntimeError`](https://python-all.ru/3.9/library/exceptions.html#RuntimeError) возбуждается, если в текущем потоке нет запущенного цикла.240241> **Важно**242>243> Сохраните ссылку на результат этой функции, чтобы избежать исчезновения задачи во время выполнения.244245Добавлено в версии 3.7.246247Изменено в версии 3.8: Добавлен параметр `name`.248249## [Ожидание](https://python-all.ru/3.9/library/asyncio-task.html#id5)250251#### `coroutine asyncio.sleep(delay, result=None, *, loop=None)`252253Приостанавливает выполнение на *delay* секунд.254255Если *result* указан, он возвращается вызывающей стороне после завершения корутины.256257`sleep()` всегда приостанавливает текущую задачу, позволяя выполняться другим задачам.258259Установка задержки в 0 обеспечивает оптимизированный путь, позволяющий выполняться другим задачам. Это может использоваться длительными функциями, чтобы избежать блокировки цикла событий на всё время вызова функции.260261Устарело с версии 3.8, будет удалено в версии 3.10: Параметр *loop*.262263Пример корутины, выводящей текущую дату каждую секунду в течение 5 секунд:264265```python266import asyncio267import datetime268269async def display_date():270 loop = asyncio.get_running_loop()271 end_time = loop.time() + 5.0272 while True:273 print(datetime.datetime.now())274 if (loop.time() + 1.0) >= end_time:275 break276 await asyncio.sleep(1)277278asyncio.run(display_date())279```280281## [Одновременный запуск задач](https://python-all.ru/3.9/library/asyncio-task.html#id6)282283#### `awaitable asyncio.gather(*aws, loop=None, return_exceptions=False)`284285Выполняет [ожидаемые объекты](https://python-all.ru/3.9/library/asyncio-task.html#asyncio-awaitables) из последовательности *aws* *одновременно*.286287Если любой ожидаемый объект из *aws* является корутиной, он автоматически планируется как задача.288289Если все ожидаемые объекты завершены успешно, результатом является сводный список возвращённых значений. Порядок значений результата соответствует порядку ожидаемых объектов в *aws*.290291Если *return\_exceptions* равно `False` (по умолчанию), первое возбуждённое исключение немедленно распространяется на задачу, ожидающую `gather()`. Остальные ожидаемые объекты в последовательности *aws* **не будут отменены** и продолжат выполнение.292293Если *return\_exceptions* равно `True`, исключения обрабатываются так же, как успешные результаты, и объединяются в списке результатов.294295Если `gather()` *отменён*, все переданные ожидаемые объекты (которые ещё не завершились) также *отменяются*.296297Если любая задача или Future из последовательности *aws* *отменена*, это рассматривается так, как если бы она возбудила [`CancelledError`](https://python-all.ru/3.9/library/asyncio-exceptions.html#asyncio.CancelledError) – вызов `gather()` в этом случае **не** отменяется. Это сделано для предотвращения ситуации, когда отмена одной переданной задачи или Future приводит к отмене других задач или Future.298299Устарело с версии 3.8, будет удалено в версии 3.10: Параметр *loop*.300301Пример:302303```python304import asyncio305306async def factorial(name, number):307 f = 1308 for i in range(2, number + 1):309 print(f"Task {name}: Compute factorial({number}), currently i={i}...")310 await asyncio.sleep(1)311 f *= i312 print(f"Task {name}: factorial({number}) = {f}")313 return f314315async def main():316 # Запланировать три вызова *конкурентно*:317 L = await asyncio.gather(318 factorial("A", 2),319 factorial("B", 3),320 factorial("C", 4),321 )322 print(L)323324asyncio.run(main())325326# Ожидаемый вывод:327#328# Задача A: вычисление factorial(2), сейчас i=2...329# Задача B: вычисление factorial(3), сейчас i=2...330# Задача C: вычисление factorial(4), сейчас i=2...331# Задача A: factorial(2) = 2332# Задача B: вычисление factorial(3), сейчас i=3...333# Задача C: вычисление factorial(4), сейчас i=3...334# Задача B: factorial(3) = 6335# Задача C: вычисление factorial(4), сейчас i=4...336# Задача C: factorial(4) = 24337# [2, 6, 24]338```339340> **Примечание**341>342> Если *return\_exceptions* равно False, отмена gather() после того, как он был помечен как завершённый, не отменит ни один из переданных ожидаемых объектов. Например, gather может быть помечен как завершённый после распространения исключения вызывающему коду; следовательно, вызов `gather.cancel()` после перехвата исключения (возбуждённого одним из ожидаемых объектов) из gather не отменит другие ожидаемые объекты.343344Изменено в версии 3.7: Если сам *gather* отменён, отмена распространяется независимо от *return\_exceptions*.345346## [Защита от отмены](https://python-all.ru/3.9/library/asyncio-task.html#id7)347348#### `awaitable asyncio.shield(aw, *, loop=None)`349350Защищает [ожидаемый объект](https://python-all.ru/3.9/library/asyncio-task.html#asyncio-awaitables) от [`cancelled`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.Task.cancel).351352Если *aw* является корутиной, она автоматически планируется как задача.353354Выражение:355356```python357res = await shield(something())358```359360эквивалентно:361362```python363res = await something()364```365366*За исключением* того, что если содержащая его корутина отменяется, задача, выполняющаяся в `something()`, не отменяется. С точки зрения `something()` отмена не произошла. Хотя её вызывающий код всё ещё отменён, поэтому выражение «await» по-прежнему возбуждает [`CancelledError`](https://python-all.ru/3.9/library/asyncio-exceptions.html#asyncio.CancelledError).367368Если `something()` отменяется другими средствами (т.е. изнутри самой себя), это также отменит `shield()`.369370Если требуется полностью игнорировать отмену (не рекомендуется), функцию `shield()` следует комбинировать с конструкцией try/except следующим образом:371372```python373try:374 res = await shield(something())375except CancelledError:376 res = None377```378379Устарело с версии 3.8, будет удалено в версии 3.10: Параметр *loop*.380381## [Тайм-ауты](https://python-all.ru/3.9/library/asyncio-task.html#id8)382383#### `coroutine asyncio.wait_for(aw, timeout, *, loop=None)`384385Ожидает завершения *aw* [ожидаемого объекта](https://python-all.ru/3.9/library/asyncio-task.html#asyncio-awaitables) с таймаутом.386387Если *aw* является корутиной, она автоматически планируется как задача.388389*timeout* может быть либо `None`, либо числом с плавающей запятой или целым числом секунд ожидания. Если *timeout* равно `None`, блокирует выполнение до завершения future.390391Если происходит таймаут, он отменяет задачу и возбуждает [`asyncio.TimeoutError`](https://python-all.ru/3.9/library/asyncio-exceptions.html#asyncio.TimeoutError).392393Чтобы избежать задачи [`cancellation`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.Task.cancel), оберните её в [`shield()`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.shield).394395Функция будет ждать, пока future не будет фактически отменена, поэтому общее время ожидания может превысить *timeout*. Если во время отмены произойдёт исключение, оно будет распространено.396397Если ожидание отменяется, future *aw* также отменяется.398399Устарело с версии 3.8, будет удалено в версии 3.10: Параметр *loop*.400401Пример:402403```python404async def eternity():405 # Спать в течение часа406 await asyncio.sleep(3600)407 print('yay!')408409async def main():410 # Ждать не более 1 секунды411 try:412 await asyncio.wait_for(eternity(), timeout=1.0)413 except asyncio.TimeoutError:414 print('timeout!')415416asyncio.run(main())417418# Ожидаемый вывод:419#420# тайм-аут!421```422423Изменено в версии 3.7: Когда *aw* отменяется из-за таймаута, `wait_for` ожидает отмены *aw*. Ранее оно немедленно вызывало [`asyncio.TimeoutError`](https://python-all.ru/3.9/library/asyncio-exceptions.html#asyncio.TimeoutError).424425## [Примитивы ожидания](https://python-all.ru/3.9/library/asyncio-task.html#id9)426427#### `coroutine asyncio.wait(aws, *, loop=None, timeout=None, return_when=ALL_COMPLETED)`428429Запускает [ожидаемые объекты](https://python-all.ru/3.9/library/asyncio-task.html#asyncio-awaitables) в *aws*\\nитерируемом объекте конкурентно и блокируется до выполнения условия, заданного\\n*return\_when*.430431Итерируемый объект *aws* не должен быть пустым.432433Возвращает два набора задач/future: `(done, pending)`.434435Использование:436437```python438done, pending = await asyncio.wait(aws)439```440441*timeout* (число с плавающей точкой или целое) позволяет указать максимальное время ожидания в секундах перед возвратом результата.442443Обратите внимание, что эта функция не вызывает [`asyncio.TimeoutError`](https://python-all.ru/3.9/library/asyncio-exceptions.html#asyncio.TimeoutError). Объекты Future или задачи, не завершённые к моменту таймаута, просто возвращаются во втором наборе.444445*return\_when* указывает, когда эта функция должна вернуть результат. Это должна быть одна из следующих констант:446447| Константа | Описание |448| --- | --- |449| `FIRST_COMPLETED` | Функция вернёт результат, когда любой future завершится или будет отменён. |450| `FIRST_EXCEPTION` | Функция вернёт результат, когда любой future завершится, возбудив исключение. Если ни один future не возбудит исключение, это эквивалентно `ALL_COMPLETED`. |451| `ALL_COMPLETED` | Функция вернёт результат, когда все future завершатся или будут отменены. |452453В отличие от [`wait_for()`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.wait_for), `wait()` не отменяет futures при возникновении таймаута.454455Устарело с версии 3.8: Если любой ожидаемый объект в *aws* является корутиной, она автоматически\\nпланируется как задача. Передача объектов-корутин непосредственно в\\n`wait()` устарела, поскольку это приводит к\\n[запутанному поведению](https://python-all.ru/3.9/library/asyncio-task.html#asyncio-example-wait-coroutine).456457Устарело с версии 3.8, будет удалено в версии 3.10: Параметр *loop*.458459> **Примечание**460>461> `wait()` автоматически планирует корутины как задачи и затем возвращает эти неявно созданные объекты задач в `(done, pending)` наборах. Поэтому следующий код не будет работать, как ожидается:462>463> ```python464> async def foo():465> return 42466>467> coro = foo()468> done, pending = await asyncio.wait({coro})469>470> if coro in done:471> # Эта ветка никогда не будет выполнена!472> ```473>474> Вот как можно исправить приведённый выше фрагмент:475>476> ```python477> async def foo():478> return 42479>480> task = asyncio.create_task(foo())481> done, pending = await asyncio.wait({task})482>483> if task in done:484> # Теперь всё будет работать как ожидается.485> ```486487Устарело с версии 3.8, будет удалено в версии 3.11: Передача объектов-корутин непосредственно в `wait()`\\nустарела.488489#### `asyncio.as_completed(aws, *, loop=None, timeout=None)`490491Запускает [ожидаемые объекты](https://python-all.ru/3.9/library/asyncio-task.html#asyncio-awaitables) из итерируемого *aws* одновременно. Возвращает итератор корутин. Каждую возвращённую корутину можно ожидать, чтобы получить следующий по порядку результат из итерируемого набора оставшихся ожидаемых объектов.492493Вызывает [`asyncio.TimeoutError`](https://python-all.ru/3.9/library/asyncio-exceptions.html#asyncio.TimeoutError), если время ожидания истекает до того, как все Future будут завершены.494495Устарело с версии 3.8, будет удалено в версии 3.10: Параметр *loop*.496497Пример:498499```python500for coro in as_completed(aws):501 earliest_result = await coro502 # ...503```504505## [Запуск в потоках](https://python-all.ru/3.9/library/asyncio-task.html#id10)506507#### `coroutine asyncio.to_thread(func, /, *args, **kwargs)`508509Асинхронно запускает функцию *func* в отдельном потоке.510511Любые \*args и \*\*kwargs, переданные в эту функцию, напрямую передаются в *func*. Также распространяется текущий [`contextvars.Context`](https://python-all.ru/3.9/library/contextvars.html#contextvars.Context), что позволяет обращаться к контекстным переменным из потока цикла событий в отдельном потоке.512513Возвращает корутину, которую можно ожидать для получения конечного результата *func*.514515Эта корутинная функция в первую очередь предназначена для выполнения\\nфункций/методов, связанных с вводом-выводом, которые в противном случае блокировали бы цикл событий, если\\nбы они выполнялись в основном потоке. Например:516517```python518def blocking_io():519 print(f"start blocking_io at {time.strftime('%X')}")520 # Обратите внимание, что time.sleep() можно заменить любой блокирующей521 # операцией ввода-вывода, например файловыми операциями.522 time.sleep(1)523 print(f"blocking_io complete at {time.strftime('%X')}")524525async def main():526 print(f"started main at {time.strftime('%X')}")527528 await asyncio.gather(529 asyncio.to_thread(blocking_io),530 asyncio.sleep(1))531532 print(f"finished main at {time.strftime('%X')}")533534asyncio.run(main())535536# Ожидаемый вывод:537#538# запущен main в 19:50:53539# запуск blocking_io в 19:50:53540# blocking_io завершён в 19:50:54541# main завершён в 19:50:54542```543544Прямой вызов *blocking\_io()* в любой корутине заблокирует цикл событий на время своего выполнения, что приведет к дополнительной секунде времени выполнения. Вместо этого, используя *asyncio.to\_thread()*, можно запустить её в отдельном потоке, не блокируя цикл событий.545546> **Примечание**547>548> Из-за [GIL](https://python-all.ru/3.9/glossary.html#term-gil), *asyncio.to\_thread()* обычно может использоваться только dля того, чтобы сделать функции, связанные с вводом-выводом, неблокирующими. Однако для модулей расширения, которые освобождают GIL, или альтернативных реализаций Python, которые не имеют его, *asyncio.to\_thread()* также можно использовать для функций, связанных с процессором.549550Новое в версии 3.9.551552## [Планирование из других потоков](https://python-all.ru/3.9/library/asyncio-task.html#id11)553554#### `asyncio.run_coroutine_threadsafe(coro, loop)`555556Отправляет корутину в указанный цикл событий. Потокобезопасно.557558Возвращает [`concurrent.futures.Future`](https://python-all.ru/3.9/library/concurrent.futures.html#concurrent.futures.Future) для ожидания результата из другого потока операционной системы.559560Эта функция предназначена для вызова из другого потока операционной системы, отличного от того, в котором работает цикл событий. Пример:561562```python563# Создать корутину564coro = asyncio.sleep(1, result=3)565566# Отправить корутину в заданный цикл567future = asyncio.run_coroutine_threadsafe(coro, loop)568569# Ожидать результат с необязательным аргументом таймаута570assert future.result(timeout) == 3571```572573Если в корутине возникло исключение, возвращаемый объект Future получит уведомление. Его также можно использовать для отмены задачи в цикле событий:574575```python576try:577 result = future.result(timeout)578except asyncio.TimeoutError:579 print('The coroutine took too long, cancelling the task...')580 future.cancel()581except Exception as exc:582 print(f'The coroutine raised an exception: {exc!r}')583else:584 print(f'The coroutine returned: {result!r}')585```586587См. раздел [concurrency and multithreading](https://python-all.ru/3.9/library/asyncio-dev.html#asyncio-multithreading) документации.588589В отличие от других функций asyncio, эта функция требует явной передачи аргумента *loop* .590591Новое в версии 3.5.1.592593## [Интроспекция](https://python-all.ru/3.9/library/asyncio-task.html#id12)594595#### `asyncio.current_task(loop=None)`596597Возвращает экземпляр текущей выполняющейся [`Task`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.Task) или `None`, если нет выполняющейся задачи.598599Если *loop* равен `None`, используется [`get_running_loop()`](https://python-all.ru/3.9/library/asyncio-eventloop.html#asyncio.get_running_loop) для получения текущего цикла.600601Добавлено в версии 3.7.602603#### `asyncio.all_tasks(loop=None)`604605Возвращает набор ещё не завершённых объектов [`Task`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.Task), выполняемых циклом.606607Если *loop* равен `None`, [`get_running_loop()`](https://python-all.ru/3.9/library/asyncio-eventloop.html#asyncio.get_running_loop) используется для получения текущего цикла.608609Добавлено в версии 3.7.610611## [Объект Задачи](https://python-all.ru/3.9/library/asyncio-task.html#id13)612613#### `class asyncio.Task(coro, *, loop=None, name=None)`614615Объект [`Future-like`](https://python-all.ru/3.9/library/asyncio-future.html#asyncio.Future), выполняющий корутину Python [корутину](https://python-all.ru/3.9/library/asyncio-task.html#coroutine). Непотокобезопасный.616617Задачи используются для выполнения корутин в циклах событий. Если корутина ожидает Future, задача приостанавливает выполнение корутины и ждёт завершения Future. Когда Future *завершён*, выполнение обёрнутой корутины возобновляется.618619Циклы событий используют кооперативное планирование: цикл событий выполняет по одной задаче за раз. Пока задача ожидает завершения Future, цикл событий выполняет другие задачи, колбэки или производит операции ввода-вывода.620621Используйте высокоуровневую функцию [`asyncio.create_task()`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.create_task) для создания задач или низкоуровневые функции [`loop.create_task()`](https://python-all.ru/3.9/library/asyncio-eventloop.html#asyncio.loop.create_task) или [`ensure_future()`](https://python-all.ru/3.9/library/asyncio-future.html#asyncio.ensure_future). Ручное создание экземпляров задач не рекомендуется.622623Чтобы отменить выполняющуюся задачу, используйте метод [`cancel()`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.Task.cancel). Его вызов приведёт к тому, что задача возбудит исключение [`CancelledError`](https://python-all.ru/3.9/library/asyncio-exceptions.html#asyncio.CancelledError) в обёрнутой корутине. Если во время отмены корутина ожидает объект Future, этот объект Future будет отменён.624625[`cancelled()`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.Task.cancelled) можно использовать для проверки, была ли задача отменена. Метод возвращает `True`, если обёрнутая корутина не подавила исключение [`CancelledError`](https://python-all.ru/3.9/library/asyncio-exceptions.html#asyncio.CancelledError) и была действительно отменена.626627[`asyncio.Task`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.Task) наследует от [`Future`](https://python-all.ru/3.9/library/asyncio-future.html#asyncio.Future) все свои API, за исключением [`Future.set_result()`](https://python-all.ru/3.9/library/asyncio-future.html#asyncio.Future.set_result) и [`Future.set_exception()`](https://python-all.ru/3.9/library/asyncio-future.html#asyncio.Future.set_exception).628629Задачи поддерживают модуль [`contextvars`](https://python-all.ru/3.9/library/contextvars.html#module-contextvars). Когда создаётся задача,\\nона копирует текущий контекст и затем выполняет свою\\nкорутину в скопированном контексте.630631Изменено в версии 3.7: Добавлена поддержка модуля [`contextvars`](https://python-all.ru/3.9/library/contextvars.html#module-contextvars).632633Изменено в версии 3.8: Добавлен параметр `name`.634635Устарело с версии 3.8, будет удалено в версии 3.10: Параметр *loop*.636637#### `cancel(msg=None)`638639Запрашивает отмену задачи.640641Обеспечивает выброс исключения [`CancelledError`](https://python-all.ru/3.9/library/asyncio-exceptions.html#asyncio.CancelledError) в обёрнутую корутину на следующем цикле событийного цикла.642643Затем корутина имеет возможность очистить ресурсы или даже отклонить\\nзапрос, подавив исключение с помощью блока [`try`](https://python-all.ru/3.9/reference/compound_stmts.html#try) …\\n… `except CancelledError` … [`finally`](https://python-all.ru/3.9/reference/compound_stmts.html#finally).\\nПоэтому, в отличие от [`Future.cancel()`](https://python-all.ru/3.9/library/asyncio-future.html#asyncio.Future.cancel), [`Task.cancel()`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.Task.cancel) не\\nгарантирует, что задача будет отменена, хотя полное подавление отмены\\nне является распространённой практикой и активно не рекомендуется.644645Изменено в версии 3.9: Добавлен параметр `msg`.646647Следующий пример показывает, как корутины могут перехватить запрос отмены:648649```python650async def cancel_me():651 print('cancel_me(): before sleep')652653 try:654 # Ждать 1 час655 await asyncio.sleep(3600)656 except asyncio.CancelledError:657 print('cancel_me(): cancel sleep')658 raise659 finally:660 print('cancel_me(): after sleep')661662async def main():663 # Создать задачу "cancel_me"664 task = asyncio.create_task(cancel_me())665666 # Ждать 1 секунду667 await asyncio.sleep(1)668669 task.cancel()670 try:671 await task672 except asyncio.CancelledError:673 print("main(): cancel_me is cancelled now")674675asyncio.run(main())676677# Ожидаемый вывод:678#679# cancel_me(): перед сном680# cancel_me(): отмена сна681# cancel_me(): после сна682# main(): cancel_me теперь отменён683```684685#### `cancelled()`686687Return `True` if the Task is *cancelled*.688689The Task is *cancelled* when the cancellation was requested with [`cancel()`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.Task.cancel) and the wrapped coroutine propagated the [`CancelledError`](https://python-all.ru/3.9/library/asyncio-exceptions.html#asyncio.CancelledError) exception thrown into it.690691#### `done()`692693Возвращает `True`, если задача *завершена*.694695Задача *завершена*, когда обёрнутая корутина вернула значение, возбудила исключение или задача была отменена.696697#### `result()`698699Возвращает результат задачи.700701Если задача *завершена*, возвращается результат обёрнутой корутины (или, если корутина возбудила исключение, это исключение возбуждается повторно).702703Если задача была *отменена*, этот метод возбуждает исключение [`CancelledError`](https://python-all.ru/3.9/library/asyncio-exceptions.html#asyncio.CancelledError).704705Если результат задачи ещё не доступен, этот метод возбуждает исключение [`InvalidStateError`](https://python-all.ru/3.9/library/asyncio-exceptions.html#asyncio.InvalidStateError).706707#### `exception()`708709Возвращает исключение задачи.710711Если обёрнутая корутина возбудила исключение, возвращается это исключение. Если корутина завершилась нормально, этот метод возвращает `None`.712713Если задача была *отменена*, этот метод возбуждает исключение [`CancelledError`](https://python-all.ru/3.9/library/asyncio-exceptions.html#asyncio.CancelledError).714715Если задача ещё не *завершена*, этот метод возбуждает исключение [`InvalidStateError`](https://python-all.ru/3.9/library/asyncio-exceptions.html#asyncio.InvalidStateError).716717#### `add_done_callback(callback, *, context=None)`718719Добавляет колбэк, который будет выполнен, когда задача *завершена*.720721Этот метод следует использовать только в низкоуровневом коде, основанном на колбэках.722723Подробнее см. в документации [`Future.add_done_callback()`](https://python-all.ru/3.9/library/asyncio-future.html#asyncio.Future.add_done_callback).724725#### `remove_done_callback(callback)`726727Удаляет *колбэк* из списка колбэков.728729Этот метод следует использовать только в низкоуровневом коде, основанном на колбэках.730731Подробнее см. в документации [`Future.remove_done_callback()`](https://python-all.ru/3.9/library/asyncio-future.html#asyncio.Future.remove_done_callback).732733#### `get_stack(*, limit=None)`734735Возвращает список кадров стека для этой задачи.736737Если обёрнутая корутина не завершена, возвращается стек, в котором она приостановлена. Если корутина успешно завершилась или была отменена, возвращается пустой список. Если корутина была завершена исключением, возвращается список кадров трассировки.738739Кадры всегда упорядочены от старых к новым.740741Для приостановленной корутины возвращается только один кадр стека.742743Необязательный аргумент *limit* задаёт максимальное количество возвращаемых кадров; по умолчанию возвращаются все доступные кадры. Порядок возвращаемого списка различается в зависимости от того, возвращается стек или трассировка: возвращаются новейшие кадры стека, но старейшие кадры трассировки. (Это соответствует поведению модуля traceback.)744745#### `print_stack(*, limit=None, file=None)`746747Печатает стек или трассировку для этой задачи.748749Результат аналогичен выводу модуля traceback для кадров, полученных с помощью [`get_stack()`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.Task.get_stack).750751Аргумент *limit* передаётся непосредственно в [`get_stack()`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.Task.get_stack).752753Аргумент *file* – это поток ввода-вывода, в который записывается вывод; по умолчанию вывод записывается в [`sys.stderr`](https://python-all.ru/3.9/library/sys.html#sys.stderr).754755#### `get_coro()`756757Возвращает объект корутины, обёрнутый [`Task`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.Task).758759Новое в версии 3.8.760761#### `get_name()`762763Возвращает имя задачи.764765Если задаче не было явно присвоено имя, стандартная реализация задач asyncio генерирует имя по умолчанию при создании.766767Новое в версии 3.8.768769#### `set_name(value)`770771Устанавливает имя задачи.772773Аргумент *value* может быть любым объектом, который затем преобразуется в строку.774775В стандартной реализации задач имя будет видно в [`repr()`](https://python-all.ru/3.9/library/functions.html#repr)-выводе объекта задачи.776777Новое в версии 3.8.778779## [Корутины на основе генераторов](https://python-all.ru/3.9/library/asyncio-task.html#id14)780781> **Примечание**782>783> Support for generator-based coroutines is **устарела** и удалена в Python 3.11.784785Корутины на основе генераторов предшествуют синтаксису async/await. Они представляют собой генераторы Python, использующие выражения `yield from` для ожидания Future и других корутин.786787Корутины на основе генераторов следует декорировать с помощью [`@asyncio.coroutine`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.coroutine), хотя это не требуется.788789#### `@asyncio.coroutine`790791Декоратор для пометки корутин на основе генераторов.792793Этот декоратор позволяет старым корутинам на основе генераторов быть совместимыми с кодом async/await:794795```python796@asyncio.coroutine797def old_style_coroutine():798 yield from asyncio.sleep(1)799800async def main():801 await old_style_coroutine()802```803804Этот декоратор не следует использовать для [`async def`](https://python-all.ru/3.9/reference/compound_stmts.html#async-def) корутин.805806Устарело с версии 3.8, будет удалено в версии 3.11: Вместо этого используйте [`async def`](https://python-all.ru/3.9/reference/compound_stmts.html#async-def).807808#### `asyncio.iscoroutine(obj)`809810Возвращает `True`, если *obj* является [объектом корутины](https://python-all.ru/3.9/library/asyncio-task.html#coroutine).811812Этот метод отличается от [`inspect.iscoroutine()`](https://python-all.ru/3.9/library/inspect.html#inspect.iscoroutine) тем, что возвращает `True` для корутин на основе генераторов.813814#### `asyncio.iscoroutinefunction(func)`815816Возвращает `True`, если *func* является [корутинной функцией](https://python-all.ru/3.9/library/asyncio-task.html#coroutine).817818Этот метод отличается от [`inspect.iscoroutinefunction()`](https://python-all.ru/3.9/library/inspect.html#inspect.iscoroutinefunction) тем, что возвращает `True` для корутинных функций на основе генераторов, декорированных с помощью [`@coroutine`](https://python-all.ru/3.9/library/asyncio-task.html#asyncio.coroutine).819