asyncio-task.md
1> **Источник:** https://python-all.ru/3.7/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.7/library/asyncio-task.html#coroutines)12- [Ожидаемые объекты](https://python-all.ru/3.7/library/asyncio-task.html#awaitables)13- [Запуск asyncio-программы](https://python-all.ru/3.7/library/asyncio-task.html#running-an-asyncio-program)14- [Создание задач](https://python-all.ru/3.7/library/asyncio-task.html#creating-tasks)15- [Приостановка выполнения](https://python-all.ru/3.7/library/asyncio-task.html#sleeping)16- [Одновременное выполнение задач](https://python-all.ru/3.7/library/asyncio-task.html#running-tasks-concurrently)17- [Защита от отмены](https://python-all.ru/3.7/library/asyncio-task.html#shielding-from-cancellation)18- [Тайм-ауты](https://python-all.ru/3.7/library/asyncio-task.html#timeouts)19- [Примитивы ожидания](https://python-all.ru/3.7/library/asyncio-task.html#waiting-primitives)20- [Планирование из других потоков](https://python-all.ru/3.7/library/asyncio-task.html#scheduling-from-other-threads)21- [Интроспекция](https://python-all.ru/3.7/library/asyncio-task.html#introspection)22- [Объект задачи](https://python-all.ru/3.7/library/asyncio-task.html#task-object)23- [Корутины на основе генераторов](https://python-all.ru/3.7/library/asyncio-task.html#generator-based-coroutines)2425## [Корутины](https://python-all.ru/3.7/library/asyncio-task.html#id1)2627Корутины, объявленные с помощью синтаксиса async/await, являются предпочтительным способом написания приложений asyncio. Например, следующий фрагмент кода (требуется Python 3.7+) выводит «hello», ждёт 1 секунду, а затем выводит «world»:2829```python30>>> import asyncio3132>>> async def main():33... print('hello')34... await asyncio.sleep(1)35... print('world')3637>>> asyncio.run(main())38hello39world40```4142Обратите внимание, что простой вызов корутины не запланирует её выполнение:4344```python45>>> main()46<coroutine object main at 0x1053bb7c8>47```4849Для фактического запуска корутины asyncio предоставляет три основных механизма:5051- Функция [`asyncio.run()`](https://python-all.ru/3.7/library/asyncio-task.html#asyncio.run) для запуска точки входа верхнего уровня – функции «main()» (см. пример выше.)52- Ожидание корутины. Следующий фрагмент кода выведет «hello» после ожидания в 1 секунду, а затем выведет «world» после ожидания *ещё* 2 секунд:5354 ```python55 import asyncio56 import time5758 async def say_after(delay, what):59 await asyncio.sleep(delay)60 print(what)6162 async def main():63 print(f"started at {time.strftime('%X')}")6465 await say_after(1, 'hello')66 await say_after(2, 'world')6768 print(f"finished at {time.strftime('%X')}")6970 asyncio.run(main())71 ```7273 Ожидаемый вывод:7475 ```python76 started at 17:13:5277 hello78 world79 finished at 17:13:5580 ```81- Функция [`asyncio.create_task()`](https://python-all.ru/3.7/library/asyncio-task.html#asyncio.create_task) для параллельного запуска корутин в качестве asyncio [`Tasks`](https://python-all.ru/3.7/library/asyncio-task.html#asyncio.Task).8283 Давайте изменим пример выше и запустим две `say_after` корутины *параллельно*:8485 ```python86 async def main():87 task1 = asyncio.create_task(88 say_after(1, 'hello'))8990 task2 = asyncio.create_task(91 say_after(2, 'world'))9293 print(f"started at {time.strftime('%X')}")9495 # Ожидать завершения обеих задач (должно занять96 # около 2 секунд).97 await task198 await task299100 print(f"finished at {time.strftime('%X')}")101 ```102103 Обратите внимание, что ожидаемый вывод теперь показывает, что фрагмент выполняется на 1 секунду быстрее, чем раньше:104105 ```python106 started at 17:14:32107 hello108 world109 finished at 17:14:34110 ```111112## [Ожидаемые объекты](https://python-all.ru/3.7/library/asyncio-task.html#id2)113114Говорят, что объект является **ожидаемым** объектом, если его можно использовать в выражении [`await`](https://python-all.ru/3.7/reference/expressions.html#await). Многие API asyncio предназначены для принятия ожидаемых объектов.115116Существует три основных типа *ожидаемых* объектов: **корутины**, **задачи** и **future**.117118Корутины119120Корутины Python являются *ожидаемыми объектами*, а значит, их можно ожидать из других корутин:121122```python123import asyncio124125async def nested():126 return 42127128async def main():129 # Если просто вызвать "nested()", ничего не произойдет.130 # Создается объект корутины, но он не ожидается,131 # поэтому он *вообще не выполнится*.132 nested()133134 # Давайте поступим иначе и теперь ожидаем его:135 print(await nested()) # выведет "42".136137asyncio.run(main())138```139140> **Важно**141>142> В данной документации термин «корутина» может использоваться для двух тесно связанных понятий:143>144> - *корутинная функция*: функция [`async def`](https://python-all.ru/3.7/reference/compound_stmts.html#async-def);145> - *объект корутины*: объект, возвращаемый при вызове *корутинной функции*.146147asyncio также поддерживает устаревшие [корутины на основе генераторов](https://python-all.ru/3.7/library/asyncio-task.html#asyncio-generator-based-coro).148149Задачи150151*Задачи* используются для планирования корутин *параллельно*.152153Когда корутина обёрнута в *задачу* с помощью таких функций, как [`asyncio.create_task()`](https://python-all.ru/3.7/library/asyncio-task.html#asyncio.create_task), корутина автоматически планируется к скорому выполнению:154155```python156import asyncio157158async def nested():159 return 42160161async def main():162 # Запланировать выполнение nested() вскоре конкурентно163 # с "main()".164 task = asyncio.create_task(nested())165166 # "задача" теперь можно использовать для отмены "nested()" или167 # можно просто применить await, чтобы дождаться завершения:168 await task169170asyncio.run(main())171```172173Future174175[`Future`](https://python-all.ru/3.7/library/asyncio-future.html#asyncio.Future) – это специальный **низкоуровневый** ожидаемый объект, который представляет **конечный результат** асинхронной операции.176177Когда объект Future *ожидается*, это означает, что корутина будет ожидать, пока Future не будет разрешён в каком-то другом месте.178179Объекты Future в asyncio необходимы для того, чтобы код, основанный на колбэках, мог использоваться с async/await.180181Обычно **нет необходимости** создавать объекты Future в коде уровня приложения.182183Объекты Future, иногда предоставляемые библиотеками и некоторыми API asyncio, можно ожидать (await):184185```python186async def main():187 await function_that_returns_a_future_object()188189 # это также допустимо:190 await asyncio.gather(191 function_that_returns_a_future_object(),192 some_python_coroutine()193 )194```195196Хороший пример низкоуровневой функции, возвращающей объект Future – [`loop.run_in_executor()`](https://python-all.ru/3.7/library/asyncio-eventloop.html#asyncio.loop.run_in_executor).197198## [Запуск программы asyncio](https://python-all.ru/3.7/library/asyncio-task.html#id3)199200#### `asyncio.run(coro, *, debug=False)`201202Выполняет [корутину](https://python-all.ru/3.7/glossary.html#term-coroutine) *coro* и возвращает результат.203204Эта функция запускает переданную корутину, заботясь об управлении циклом событий asyncio и *финализации асинхронных генераторов*.205206Эту функцию нельзя вызывать, когда в том же потоке выполняется другой цикл событий asyncio.207208Если *debug* равно `True`, цикл событий будет запущен в режиме отладки.209210Эта функция всегда создаёт новый цикл событий и закрывает его в конце. Её следует использовать в качестве главной точки входа для программ asyncio, и в идеале она должна вызываться только один раз.211212Пример:213214```python215async def main():216 await asyncio.sleep(1)217 print('hello')218219asyncio.run(main())220```221222Новое в версии 3.7: **Важно:** эта функция была добавлена в asyncio в Python 3.7 на [временной основе](https://python-all.ru/3.7/glossary.html#term-provisional-api).223224## [Создание задач](https://python-all.ru/3.7/library/asyncio-task.html#id4)225226#### `asyncio.create_task(coro)`227228Wrap the *coro* [coroutine](https://python-all.ru/3.7/library/asyncio-task.html#coroutine) into a [`Task`](https://python-all.ru/3.7/library/asyncio-task.html#asyncio.Task) and schedule its execution. Return the Task object.229230Задача выполняется в цикле, возвращаемом [`get_running_loop()`](https://python-all.ru/3.7/library/asyncio-eventloop.html#asyncio.get_running_loop); [`RuntimeError`](https://python-all.ru/3.7/library/exceptions.html#RuntimeError) возбуждается, если в текущем потоке нет запущенного цикла.231232Эта функция была **добавлена в Python 3.7**. До Python 3.7 вместо неё можно использовать низкоуровневую функцию [`asyncio.ensure_future()`](https://python-all.ru/3.7/library/asyncio-future.html#asyncio.ensure_future):233234```python235async def coro():236 ...237238# В Python 3.7+239task = asyncio.create_task(coro())240...241242# Это работает во всех версиях Python, но менее читаемо243task = asyncio.ensure_future(coro())244...245```246247Добавлено в версии 3.7.248249## [Ожидание](https://python-all.ru/3.7/library/asyncio-task.html#id5)250251#### `coroutine asyncio.sleep(delay, result=None, *, loop=None)`252253Приостанавливает выполнение на *delay* секунд.254255Если *result* указан, он возвращается вызывающей стороне после завершения корутины.256257`sleep()` всегда приостанавливает текущую задачу, позволяя выполняться другим задачам.258259Аргумент *loop* устарел и будет удалён в Python 3.10.260261Пример корутины, выводящей текущую дату каждую секунду в течение 5 секунд:262263```python264import asyncio265import datetime266267async def display_date():268 loop = asyncio.get_running_loop()269 end_time = loop.time() + 5.0270 while True:271 print(datetime.datetime.now())272 if (loop.time() + 1.0) >= end_time:273 break274 await asyncio.sleep(1)275276asyncio.run(display_date())277```278279## [Одновременный запуск задач](https://python-all.ru/3.7/library/asyncio-task.html#id6)280281#### `awaitable asyncio.gather(*aws, loop=None, return_exceptions=False)`282283Выполняет [ожидаемые объекты](https://python-all.ru/3.7/library/asyncio-task.html#asyncio-awaitables) из последовательности *aws* *одновременно*.284285Если любой ожидаемый объект из *aws* является корутиной, он автоматически планируется как задача.286287Если все ожидаемые объекты завершены успешно, результатом является сводный список возвращённых значений. Порядок значений результата соответствует порядку ожидаемых объектов в *aws*.288289Если *return\_exceptions* равно `False` (по умолчанию), первое возбуждённое исключение немедленно распространяется на задачу, ожидающую `gather()`. Остальные ожидаемые объекты в последовательности *aws* **не будут отменены** и продолжат выполнение.290291Если *return\_exceptions* равно `True`, исключения обрабатываются так же, как успешные результаты, и объединяются в списке результатов.292293Если `gather()` *отменён*, все переданные ожидаемые объекты (которые ещё не завершились) также *отменяются*.294295Если любая задача или Future из последовательности *aws* *отменена*, это рассматривается так, как если бы она возбудила [`CancelledError`](https://python-all.ru/3.7/library/asyncio-exceptions.html#asyncio.CancelledError) – вызов `gather()` в этом случае **не** отменяется. Это сделано для предотвращения ситуации, когда отмена одной переданной задачи или Future приводит к отмене других задач или Future.296297Пример:298299```python300import asyncio301302async def factorial(name, number):303 f = 1304 for i in range(2, number + 1):305 print(f"Task {name}: Compute factorial({i})...")306 await asyncio.sleep(1)307 f *= i308 print(f"Task {name}: factorial({number}) = {f}")309310async def main():311 # Запланировать три вызова *конкурентно*:312 await asyncio.gather(313 factorial("A", 2),314 factorial("B", 3),315 factorial("C", 4),316 )317318asyncio.run(main())319320# Ожидаемый вывод:321#322# Задача A: вычислить factorial(2)...323# Задача B: вычислить factorial(2)...324# Задача C: вычислить factorial(2)...325# Задача A: factorial(2) = 2326# Задача B: вычислить factorial(3)...327# Задача C: вычислить factorial(3)...328# Задача B: factorial(3) = 6329# Задача C: вычислить factorial(4)...330# Задача C: factorial(4) = 24331```332333Изменено в версии 3.7: Если сам *gather* отменён, отмена распространяется независимо от *return\_exceptions*.334335## [Защита от отмены](https://python-all.ru/3.7/library/asyncio-task.html#id7)336337#### `awaitable asyncio.shield(aw, *, loop=None)`338339Защищает [ожидаемый объект](https://python-all.ru/3.7/library/asyncio-task.html#asyncio-awaitables) от [`cancelled`](https://python-all.ru/3.7/library/asyncio-task.html#asyncio.Task.cancel).340341Если *aw* является корутиной, она автоматически планируется как задача.342343Выражение:344345```python346res = await shield(something())347```348349эквивалентно:350351```python352res = await something()353```354355*За исключением* того, что если содержащая его корутина отменяется, задача, выполняющаяся в `something()`, не отменяется. С точки зрения `something()` отмена не произошла. Хотя её вызывающий код всё ещё отменён, поэтому выражение «await» по-прежнему возбуждает [`CancelledError`](https://python-all.ru/3.7/library/asyncio-exceptions.html#asyncio.CancelledError).356357Если `something()` отменяется другими средствами (т.е. изнутри самой себя), это также отменит `shield()`.358359Если требуется полностью игнорировать отмену (не рекомендуется), функцию `shield()` следует комбинировать с конструкцией try/except следующим образом:360361```python362try:363 res = await shield(something())364except CancelledError:365 res = None366```367368## [Тайм-ауты](https://python-all.ru/3.7/library/asyncio-task.html#id8)369370#### `coroutine asyncio.wait_for(aw, timeout, *, loop=None)`371372Ожидает завершения *aw* [ожидаемого объекта](https://python-all.ru/3.7/library/asyncio-task.html#asyncio-awaitables) с таймаутом.373374Если *aw* является корутиной, она автоматически планируется как задача.375376*timeout* может быть либо `None`, либо числом с плавающей запятой или целым числом секунд ожидания. Если *timeout* равно `None`, блокирует выполнение до завершения future.377378Если происходит таймаут, он отменяет задачу и возбуждает [`asyncio.TimeoutError`](https://python-all.ru/3.7/library/asyncio-exceptions.html#asyncio.TimeoutError).379380Чтобы избежать задачи [`cancellation`](https://python-all.ru/3.7/library/asyncio-task.html#asyncio.Task.cancel), оберните её в [`shield()`](https://python-all.ru/3.7/library/asyncio-task.html#asyncio.shield).381382Функция будет ждать, пока future не будет фактически отменён, поэтому общее время ожидания может превысить *тайм-аут*.383384Если ожидание отменяется, future *aw* также отменяется.385386Аргумент *loop* устарел и будет удалён в Python 3.10.387388Пример:389390```python391async def eternity():392 # Спать в течение часа393 await asyncio.sleep(3600)394 print('yay!')395396async def main():397 # Ждать не более 1 секунды398 try:399 await asyncio.wait_for(eternity(), timeout=1.0)400 except asyncio.TimeoutError:401 print('timeout!')402403asyncio.run(main())404405# Ожидаемый вывод:406#407# тайм-аут!408```409410Изменено в версии 3.7: Когда *aw* отменяется из-за таймаута, `wait_for` ожидает отмены *aw*. Ранее оно немедленно вызывало [`asyncio.TimeoutError`](https://python-all.ru/3.7/library/asyncio-exceptions.html#asyncio.TimeoutError).411412## [Примитивы ожидания](https://python-all.ru/3.7/library/asyncio-task.html#id9)413414#### `coroutine asyncio.wait(aws, *, loop=None, timeout=None, return_when=ALL_COMPLETED)`415416Запускает [ожидаемые объекты](https://python-all.ru/3.7/library/asyncio-task.html#asyncio-awaitables) из набора *aws* конкурентно и блокируется до выполнения условия, заданного *return\_when*.417418Если любой ожидаемый объект в *aws* является корутиной, он автоматически планируется как задача. Передача объектов-корутин напрямую в `wait()` устарела, так как приводит к [запутанному поведению](https://python-all.ru/3.7/library/asyncio-task.html#asyncio-example-wait-coroutine).419420Возвращает два набора задач/future: `(done, pending)`.421422Использование:423424```python425done, pending = await asyncio.wait(aws)426```427428Аргумент *loop* устарел и будет удалён в Python 3.10.429430*timeout* (число с плавающей точкой или целое) позволяет указать максимальное время ожидания в секундах перед возвратом результата.431432Обратите внимание, что эта функция не вызывает [`asyncio.TimeoutError`](https://python-all.ru/3.7/library/asyncio-exceptions.html#asyncio.TimeoutError). Объекты Future или задачи, не завершённые к моменту таймаута, просто возвращаются во втором наборе.433434*return\_when* указывает, когда эта функция должна вернуть результат. Это должна быть одна из следующих констант:435436| Константа | Описание |437| --- | --- |438| `FIRST_COMPLETED` | Функция вернёт результат, когда любой future завершится или будет отменён. |439| `FIRST_EXCEPTION` | Функция вернёт результат, когда любой future завершится, возбудив исключение. Если ни один future не возбудит исключение, это эквивалентно `ALL_COMPLETED`. |440| `ALL_COMPLETED` | Функция вернёт результат, когда все future завершатся или будут отменены. |441442В отличие от [`wait_for()`](https://python-all.ru/3.7/library/asyncio-task.html#asyncio.wait_for), `wait()` не отменяет futures при возникновении таймаута.443444> **Примечание**445>446> `wait()` автоматически планирует корутины как задачи и затем возвращает эти неявно созданные объекты задач в `(done, pending)` наборах. Поэтому следующий код не будет работать, как ожидается:447>448> ```python449> async def foo():450> return 42451>452> coro = foo()453> done, pending = await asyncio.wait({coro})454>455> if coro in done:456> # Эта ветка никогда не будет выполнена!457> ```458>459> Вот как можно исправить приведённый выше фрагмент:460>461> ```python462> async def foo():463> return 42464>465> task = asyncio.create_task(foo())466> done, pending = await asyncio.wait({task})467>468> if task in done:469> # Теперь всё будет работать как ожидается.470> ```471>472> Передача объектов-корутин напрямую в `wait()` устарела.473474#### `asyncio.as_completed(aws, *, loop=None, timeout=None)`475476Выполняет [ожидаемые объекты](https://python-all.ru/3.7/library/asyncio-task.html#asyncio-awaitables) из набора *aws* конкурентно. Возвращает итератор объектов [`Future`](https://python-all.ru/3.7/library/asyncio-future.html#asyncio.Future). Каждый возвращённый объект Future представляет собой самый ранний результат из оставшихся ожидаемых объектов.477478Вызывает [`asyncio.TimeoutError`](https://python-all.ru/3.7/library/asyncio-exceptions.html#asyncio.TimeoutError), если время ожидания истекает до того, как все Future будут завершены.479480Пример:481482```python483for f in as_completed(aws):484 earliest_result = await f485 # ...486```487488## [Планирование из других потоков](https://python-all.ru/3.7/library/asyncio-task.html#id10)489490#### `asyncio.run_coroutine_threadsafe(coro, loop)`491492Отправляет корутину в указанный цикл событий. Потокобезопасно.493494Возвращает [`concurrent.futures.Future`](https://python-all.ru/3.7/library/concurrent.futures.html#concurrent.futures.Future) для ожидания результата из другого потока операционной системы.495496Эта функция предназначена для вызова из другого потока операционной системы, отличного от того, в котором работает цикл событий. Пример:497498```python499# Создать корутину500coro = asyncio.sleep(1, result=3)501502# Отправить корутину в заданный цикл503future = asyncio.run_coroutine_threadsafe(coro, loop)504505# Ожидать результат с необязательным аргументом таймаута506assert future.result(timeout) == 3507```508509Если в корутине возникло исключение, возвращаемый объект Future получит уведомление. Его также можно использовать для отмены задачи в цикле событий:510511```python512try:513 result = future.result(timeout)514except asyncio.TimeoutError:515 print('The coroutine took too long, cancelling the task...')516 future.cancel()517except Exception as exc:518 print(f'The coroutine raised an exception: {exc!r}')519else:520 print(f'The coroutine returned: {result!r}')521```522523См. раздел [concurrency and multithreading](https://python-all.ru/3.7/library/asyncio-dev.html#asyncio-multithreading) документации.524525В отличие от других функций asyncio, эта функция требует явной передачи аргумента *loop* .526527Новое в версии 3.5.1.528529## [Интроспекция](https://python-all.ru/3.7/library/asyncio-task.html#id11)530531#### `asyncio.current_task(loop=None)`532533Возвращает экземпляр текущей выполняющейся [`Task`](https://python-all.ru/3.7/library/asyncio-task.html#asyncio.Task) или `None`, если нет выполняющейся задачи.534535Если *loop* равен `None`, используется [`get_running_loop()`](https://python-all.ru/3.7/library/asyncio-eventloop.html#asyncio.get_running_loop) для получения текущего цикла.536537Добавлено в версии 3.7.538539#### `asyncio.all_tasks(loop=None)`540541Возвращает набор ещё не завершённых объектов [`Task`](https://python-all.ru/3.7/library/asyncio-task.html#asyncio.Task), выполняемых циклом.542543Если *loop* равен `None`, [`get_running_loop()`](https://python-all.ru/3.7/library/asyncio-eventloop.html#asyncio.get_running_loop) используется для получения текущего цикла.544545Добавлено в версии 3.7.546547## [Объект Задачи](https://python-all.ru/3.7/library/asyncio-task.html#id12)548549#### `class asyncio.Task(coro, *, loop=None)`550551Объект [`Future-like`](https://python-all.ru/3.7/library/asyncio-future.html#asyncio.Future), выполняющий корутину Python [корутину](https://python-all.ru/3.7/library/asyncio-task.html#coroutine). Непотокобезопасный.552553Задачи используются для выполнения корутин в циклах событий. Если корутина ожидает Future, задача приостанавливает выполнение корутины и ждёт завершения Future. Когда Future *завершён*, выполнение обёрнутой корутины возобновляется.554555Циклы событий используют кооперативное планирование: цикл событий выполняет по одной задаче за раз. Пока задача ожидает завершения Future, цикл событий выполняет другие задачи, колбэки или производит операции ввода-вывода.556557Используйте высокоуровневую функцию [`asyncio.create_task()`](https://python-all.ru/3.7/library/asyncio-task.html#asyncio.create_task) для создания задач или низкоуровневые функции [`loop.create_task()`](https://python-all.ru/3.7/library/asyncio-eventloop.html#asyncio.loop.create_task) или [`ensure_future()`](https://python-all.ru/3.7/library/asyncio-future.html#asyncio.ensure_future). Ручное создание экземпляров задач не рекомендуется.558559Чтобы отменить выполняющуюся задачу, используйте метод [`cancel()`](https://python-all.ru/3.7/library/asyncio-task.html#asyncio.Task.cancel). Его вызов приведёт к тому, что задача возбудит исключение [`CancelledError`](https://python-all.ru/3.7/library/asyncio-exceptions.html#asyncio.CancelledError) в обёрнутой корутине. Если во время отмены корутина ожидает объект Future, этот объект Future будет отменён.560561[`cancelled()`](https://python-all.ru/3.7/library/asyncio-task.html#asyncio.Task.cancelled) можно использовать для проверки, была ли задача отменена. Метод возвращает `True`, если обёрнутая корутина не подавила исключение [`CancelledError`](https://python-all.ru/3.7/library/asyncio-exceptions.html#asyncio.CancelledError) и была действительно отменена.562563[`asyncio.Task`](https://python-all.ru/3.7/library/asyncio-task.html#asyncio.Task) наследует от [`Future`](https://python-all.ru/3.7/library/asyncio-future.html#asyncio.Future) все свои API, за исключением [`Future.set_result()`](https://python-all.ru/3.7/library/asyncio-future.html#asyncio.Future.set_result) и [`Future.set_exception()`](https://python-all.ru/3.7/library/asyncio-future.html#asyncio.Future.set_exception).564565Задачи поддерживают модуль [`contextvars`](https://python-all.ru/3.7/library/contextvars.html#module-contextvars). Когда создаётся задача,\\nона копирует текущий контекст и затем выполняет свою\\nкорутину в скопированном контексте.566567Изменено в версии 3.7: Добавлена поддержка модуля [`contextvars`](https://python-all.ru/3.7/library/contextvars.html#module-contextvars).568569#### `cancel()`570571Запрашивает отмену задачи.572573Обеспечивает выброс исключения [`CancelledError`](https://python-all.ru/3.7/library/asyncio-exceptions.html#asyncio.CancelledError) в обёрнутую корутину на следующем цикле событийного цикла.574575Затем корутина имеет возможность очистить ресурсы или даже отклонить\\nзапрос, подавив исключение с помощью блока [`try`](https://python-all.ru/3.7/reference/compound_stmts.html#try) …\\n… `except CancelledError` … [`finally`](https://python-all.ru/3.7/reference/compound_stmts.html#finally).\\nПоэтому, в отличие от [`Future.cancel()`](https://python-all.ru/3.7/library/asyncio-future.html#asyncio.Future.cancel), [`Task.cancel()`](https://python-all.ru/3.7/library/asyncio-task.html#asyncio.Task.cancel) не\\nгарантирует, что задача будет отменена, хотя полное подавление отмены\\nне является распространённой практикой и активно не рекомендуется.576577Следующий пример показывает, как корутины могут перехватить запрос отмены:578579```python580async def cancel_me():581 print('cancel_me(): before sleep')582583 try:584 # Ждать 1 час585 await asyncio.sleep(3600)586 except asyncio.CancelledError:587 print('cancel_me(): cancel sleep')588 raise589 finally:590 print('cancel_me(): after sleep')591592async def main():593 # Создать задачу "cancel_me"594 task = asyncio.create_task(cancel_me())595596 # Ждать 1 секунду597 await asyncio.sleep(1)598599 task.cancel()600 try:601 await task602 except asyncio.CancelledError:603 print("main(): cancel_me is cancelled now")604605asyncio.run(main())606607# Ожидаемый вывод:608#609# cancel_me(): перед сном610# cancel_me(): отмена сна611# cancel_me(): после сна612# main(): cancel_me теперь отменён613```614615#### `cancelled()`616617Return `True` if the Task is *cancelled*.618619The Task is *cancelled* when the cancellation was requested with [`cancel()`](https://python-all.ru/3.7/library/asyncio-task.html#asyncio.Task.cancel) and the wrapped coroutine propagated the [`CancelledError`](https://python-all.ru/3.7/library/asyncio-exceptions.html#asyncio.CancelledError) exception thrown into it.620621#### `done()`622623Возвращает `True`, если задача *завершена*.624625Задача *завершена*, когда обёрнутая корутина вернула значение, возбудила исключение или задача была отменена.626627#### `result()`628629Возвращает результат задачи.630631Если задача *завершена*, возвращается результат обёрнутой корутины (или, если корутина возбудила исключение, это исключение возбуждается повторно).632633Если задача была *отменена*, этот метод возбуждает исключение [`CancelledError`](https://python-all.ru/3.7/library/asyncio-exceptions.html#asyncio.CancelledError).634635Если результат задачи ещё не доступен, этот метод возбуждает исключение [`InvalidStateError`](https://python-all.ru/3.7/library/asyncio-exceptions.html#asyncio.InvalidStateError).636637#### `exception()`638639Возвращает исключение задачи.640641Если обёрнутая корутина возбудила исключение, возвращается это исключение. Если корутина завершилась нормально, этот метод возвращает `None`.642643Если задача была *отменена*, этот метод возбуждает исключение [`CancelledError`](https://python-all.ru/3.7/library/asyncio-exceptions.html#asyncio.CancelledError).644645Если задача ещё не *завершена*, этот метод возбуждает исключение [`InvalidStateError`](https://python-all.ru/3.7/library/asyncio-exceptions.html#asyncio.InvalidStateError).646647#### `add_done_callback(callback, *, context=None)`648649Добавляет колбэк, который будет выполнен, когда задача *завершена*.650651Этот метод следует использовать только в низкоуровневом коде, основанном на колбэках.652653Подробнее см. в документации [`Future.add_done_callback()`](https://python-all.ru/3.7/library/asyncio-future.html#asyncio.Future.add_done_callback).654655#### `remove_done_callback(callback)`656657Удаляет *колбэк* из списка колбэков.658659Этот метод следует использовать только в низкоуровневом коде, основанном на колбэках.660661Подробнее см. в документации [`Future.remove_done_callback()`](https://python-all.ru/3.7/library/asyncio-future.html#asyncio.Future.remove_done_callback).662663#### `get_stack(*, limit=None)`664665Возвращает список кадров стека для этой задачи.666667Если обёрнутая корутина не завершена, возвращается стек, в котором она приостановлена. Если корутина успешно завершилась или была отменена, возвращается пустой список. Если корутина была завершена исключением, возвращается список кадров трассировки.668669Кадры всегда упорядочены от старых к новым.670671Для приостановленной корутины возвращается только один кадр стека.672673Необязательный аргумент *limit* задаёт максимальное количество возвращаемых кадров; по умолчанию возвращаются все доступные кадры. Порядок возвращаемого списка различается в зависимости от того, возвращается стек или трассировка: возвращаются новейшие кадры стека, но старейшие кадры трассировки. (Это соответствует поведению модуля traceback.)674675#### `print_stack(*, limit=None, file=None)`676677Печатает стек или трассировку для этой задачи.678679Результат аналогичен выводу модуля traceback для кадров, полученных с помощью [`get_stack()`](https://python-all.ru/3.7/library/asyncio-task.html#asyncio.Task.get_stack).680681Аргумент *limit* передаётся непосредственно в [`get_stack()`](https://python-all.ru/3.7/library/asyncio-task.html#asyncio.Task.get_stack).682683Аргумент *file* – это поток ввода-вывода, в который записывается вывод; по умолчанию вывод записывается в [`sys.stderr`](https://python-all.ru/3.7/library/sys.html#sys.stderr).684685#### `classmethod all_tasks(loop=None)`686687Возвращает набор всех задач для цикла событий.688689По умолчанию возвращаются все задачи для текущего цикла событий. Если *loop* равен `None`, для получения текущего цикла используется функция [`get_event_loop()`](https://python-all.ru/3.7/library/asyncio-eventloop.html#asyncio.get_event_loop).690691Этот метод **устарел** и будет удалён в Python 3.9. Вместо него используйте функцию [`asyncio.all_tasks()`](https://python-all.ru/3.7/library/asyncio-task.html#asyncio.all_tasks).692693#### `classmethod current_task(loop=None)`694695Возвращает текущую выполняющуюся задачу или `None`.696697Если *loop* равен `None`, для получения текущего цикла используется функция [`get_event_loop()`](https://python-all.ru/3.7/library/asyncio-eventloop.html#asyncio.get_event_loop).698699Этот метод **устарел** и будет удалён в Python 3.9. Вместо него используйте функцию [`asyncio.current_task()`](https://python-all.ru/3.7/library/asyncio-task.html#asyncio.current_task).700701## [Корутины на основе генераторов](https://python-all.ru/3.7/library/asyncio-task.html#id13)702703> **Примечание**704>705> Поддержка корутин на основе генераторов **устарела** и запланирована к удалению в Python 3.10.706707Корутины на основе генераторов предшествуют синтаксису async/await. Они представляют собой генераторы Python, использующие выражения `yield from` для ожидания Future и других корутин.708709Корутины на основе генераторов следует декорировать с помощью [`@asyncio.coroutine`](https://python-all.ru/3.7/library/asyncio-task.html#asyncio.coroutine), хотя это не требуется.710711#### `@asyncio.coroutine`712713Декоратор для пометки корутин на основе генераторов.714715Этот декоратор позволяет старым корутинам на основе генераторов быть совместимыми с кодом async/await:716717```python718@asyncio.coroutine719def old_style_coroutine():720 yield from asyncio.sleep(1)721722async def main():723 await old_style_coroutine()724```725726Этот декоратор **устарел** и планируется к удалению в Python 3.10.727728Этот декоратор не следует использовать для [`async def`](https://python-all.ru/3.7/reference/compound_stmts.html#async-def) корутин.729730#### `asyncio.iscoroutine(obj)`731732Возвращает `True`, если *obj* является [объектом корутины](https://python-all.ru/3.7/library/asyncio-task.html#coroutine).733734Этот метод отличается от [`inspect.iscoroutine()`](https://python-all.ru/3.7/library/inspect.html#inspect.iscoroutine) тем, что возвращает `True` для корутин на основе генераторов.735736#### `asyncio.iscoroutinefunction(func)`737738Возвращает `True`, если *func* является [корутинной функцией](https://python-all.ru/3.7/library/asyncio-task.html#coroutine).739740Этот метод отличается от [`inspect.iscoroutinefunction()`](https://python-all.ru/3.7/library/inspect.html#inspect.iscoroutinefunction) тем, что возвращает `True` для корутинных функций на основе генераторов, декорированных с помощью [`@coroutine`](https://python-all.ru/3.7/library/asyncio-task.html#asyncio.coroutine).741