asyncio-task.md
1> **Источник:** https://python-all.ru/3.8/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.8/library/asyncio-task.html#coroutines)12- [Ожидаемые объекты](https://python-all.ru/3.8/library/asyncio-task.html#awaitables)13- [Запуск asyncio-программы](https://python-all.ru/3.8/library/asyncio-task.html#running-an-asyncio-program)14- [Создание задач](https://python-all.ru/3.8/library/asyncio-task.html#creating-tasks)15- [Приостановка выполнения](https://python-all.ru/3.8/library/asyncio-task.html#sleeping)16- [Одновременное выполнение задач](https://python-all.ru/3.8/library/asyncio-task.html#running-tasks-concurrently)17- [Защита от отмены](https://python-all.ru/3.8/library/asyncio-task.html#shielding-from-cancellation)18- [Тайм-ауты](https://python-all.ru/3.8/library/asyncio-task.html#timeouts)19- [Примитивы ожидания](https://python-all.ru/3.8/library/asyncio-task.html#waiting-primitives)20- [Планирование из других потоков](https://python-all.ru/3.8/library/asyncio-task.html#scheduling-from-other-threads)21- [Интроспекция](https://python-all.ru/3.8/library/asyncio-task.html#introspection)22- [Объект задачи](https://python-all.ru/3.8/library/asyncio-task.html#task-object)23- [Корутины на основе генераторов](https://python-all.ru/3.8/library/asyncio-task.html#generator-based-coroutines)2425## [Корутины](https://python-all.ru/3.8/library/asyncio-task.html#id1)2627[Корутины](https://python-all.ru/3.8/glossary.html#term-coroutine), объявленные с помощью синтаксиса 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.8/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.8/library/asyncio-task.html#asyncio.create_task) для параллельного запуска корутин в качестве asyncio [`Tasks`](https://python-all.ru/3.8/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.8/library/asyncio-task.html#id2)113114Говорят, что объект является **ожидаемым** объектом, если его можно использовать в выражении [`await`](https://python-all.ru/3.8/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.8/reference/compound_stmts.html#async-def);145> - *объект корутины*: объект, возвращаемый при вызове *корутинной функции*.146147asyncio также поддерживает устаревшие [корутины на основе генераторов](https://python-all.ru/3.8/library/asyncio-task.html#asyncio-generator-based-coro).148149Задачи150151*Задачи* используются для планирования корутин *параллельно*.152153Когда корутина обёрнута в *задачу* с помощью таких функций, как [`asyncio.create_task()`](https://python-all.ru/3.8/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.8/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.8/library/asyncio-eventloop.html#asyncio.loop.run_in_executor).197198## [Запуск программы asyncio](https://python-all.ru/3.8/library/asyncio-task.html#id3)199200#### `asyncio.run(coro, *, debug=False)`201202Выполняет [корутину](https://python-all.ru/3.8/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.223224> **Примечание**225>226> Исходный код `asyncio.run()` можно найти в\\n[Lib/asyncio/runners.py](https://python-all.ru/src/3.8/Lib/asyncio/runners.py).227228## [Создание задач](https://python-all.ru/3.8/library/asyncio-task.html#id4)229230#### `asyncio.create_task(coro, *, name=None)`231232Wrap the *coro* [coroutine](https://python-all.ru/3.8/library/asyncio-task.html#coroutine) into a [`Task`](https://python-all.ru/3.8/library/asyncio-task.html#asyncio.Task) and schedule its execution. Return the Task object.233234Если *name* не равен `None`, он устанавливается как имя задачи с помощью [`Task.set_name()`](https://python-all.ru/3.8/library/asyncio-task.html#asyncio.Task.set_name).235236Задача выполняется в цикле, возвращаемом [`get_running_loop()`](https://python-all.ru/3.8/library/asyncio-eventloop.html#asyncio.get_running_loop); [`RuntimeError`](https://python-all.ru/3.8/library/exceptions.html#RuntimeError) возбуждается, если в текущем потоке нет запущенного цикла.237238Эта функция была **добавлена в Python 3.7**. До Python 3.7 вместо неё можно использовать низкоуровневую функцию [`asyncio.ensure_future()`](https://python-all.ru/3.8/library/asyncio-future.html#asyncio.ensure_future):239240```python241async def coro():242 ...243244# В Python 3.7+245task = asyncio.create_task(coro())246...247248# Это работает во всех версиях Python, но менее читаемо249task = asyncio.ensure_future(coro())250...251```252253Добавлено в версии 3.7.254255Изменено в версии 3.8: Добавлен параметр `name`.256257## [Ожидание](https://python-all.ru/3.8/library/asyncio-task.html#id5)258259#### `coroutine asyncio.sleep(delay, result=None, *, loop=None)`260261Приостанавливает выполнение на *delay* секунд.262263Если *result* указан, он возвращается вызывающей стороне после завершения корутины.264265`sleep()` всегда приостанавливает текущую задачу, позволяя выполняться другим задачам.266267Устарело с версии 3.8, будет удалено в версии 3.10: Параметр *loop*.268269Пример корутины, выводящей текущую дату каждую секунду в течение 5 секунд:270271```python272import asyncio273import datetime274275async def display_date():276 loop = asyncio.get_running_loop()277 end_time = loop.time() + 5.0278 while True:279 print(datetime.datetime.now())280 if (loop.time() + 1.0) >= end_time:281 break282 await asyncio.sleep(1)283284asyncio.run(display_date())285```286287## [Одновременный запуск задач](https://python-all.ru/3.8/library/asyncio-task.html#id6)288289#### `awaitable asyncio.gather(*aws, loop=None, return_exceptions=False)`290291Выполняет [ожидаемые объекты](https://python-all.ru/3.8/library/asyncio-task.html#asyncio-awaitables) из последовательности *aws* *одновременно*.292293Если любой ожидаемый объект из *aws* является корутиной, он автоматически планируется как задача.294295Если все ожидаемые объекты завершены успешно, результатом является сводный список возвращённых значений. Порядок значений результата соответствует порядку ожидаемых объектов в *aws*.296297Если *return\_exceptions* равно `False` (по умолчанию), первое возбуждённое исключение немедленно распространяется на задачу, ожидающую `gather()`. Остальные ожидаемые объекты в последовательности *aws* **не будут отменены** и продолжат выполнение.298299Если *return\_exceptions* равно `True`, исключения обрабатываются так же, как успешные результаты, и объединяются в списке результатов.300301Если `gather()` *отменён*, все переданные ожидаемые объекты (которые ещё не завершились) также *отменяются*.302303Если любая задача или Future из последовательности *aws* *отменена*, это рассматривается так, как если бы она возбудила [`CancelledError`](https://python-all.ru/3.8/library/asyncio-exceptions.html#asyncio.CancelledError) – вызов `gather()` в этом случае **не** отменяется. Это сделано для предотвращения ситуации, когда отмена одной переданной задачи или Future приводит к отмене других задач или Future.304305Устарело с версии 3.8, будет удалено в версии 3.10: Параметр *loop*.306307Пример:308309```python310import asyncio311312async def factorial(name, number):313 f = 1314 for i in range(2, number + 1):315 print(f"Task {name}: Compute factorial({i})...")316 await asyncio.sleep(1)317 f *= i318 print(f"Task {name}: factorial({number}) = {f}")319320async def main():321 # Запланировать три вызова *конкурентно*:322 await asyncio.gather(323 factorial("A", 2),324 factorial("B", 3),325 factorial("C", 4),326 )327328asyncio.run(main())329330# Ожидаемый вывод:331#332# Задача A: вычислить factorial(2)...333# Задача B: вычислить factorial(2)...334# Задача C: вычислить factorial(2)...335# Задача A: factorial(2) = 2336# Задача B: вычислить factorial(3)...337# Задача C: вычислить factorial(3)...338# Задача B: factorial(3) = 6339# Задача C: вычислить factorial(4)...340# Задача C: factorial(4) = 24341```342343> **Примечание**344>345> Если *return\_exceptions* равно False, отмена gather() после того, как он был помечен как завершённый, не отменит ни один из переданных ожидаемых объектов. Например, gather может быть помечен как завершённый после распространения исключения вызывающему коду; следовательно, вызов `gather.cancel()` после перехвата исключения (возбуждённого одним из ожидаемых объектов) из gather не отменит другие ожидаемые объекты.346347Изменено в версии 3.7: Если сам *gather* отменён, отмена распространяется независимо от *return\_exceptions*.348349## [Защита от отмены](https://python-all.ru/3.8/library/asyncio-task.html#id7)350351#### `awaitable asyncio.shield(aw, *, loop=None)`352353Защищает [ожидаемый объект](https://python-all.ru/3.8/library/asyncio-task.html#asyncio-awaitables) от [`cancelled`](https://python-all.ru/3.8/library/asyncio-task.html#asyncio.Task.cancel).354355Если *aw* является корутиной, она автоматически планируется как задача.356357Выражение:358359```python360res = await shield(something())361```362363эквивалентно:364365```python366res = await something()367```368369*За исключением* того, что если содержащая его корутина отменяется, задача, выполняющаяся в `something()`, не отменяется. С точки зрения `something()` отмена не произошла. Хотя её вызывающий код всё ещё отменён, поэтому выражение «await» по-прежнему возбуждает [`CancelledError`](https://python-all.ru/3.8/library/asyncio-exceptions.html#asyncio.CancelledError).370371Если `something()` отменяется другими средствами (т.е. изнутри самой себя), это также отменит `shield()`.372373Если требуется полностью игнорировать отмену (не рекомендуется), функцию `shield()` следует комбинировать с конструкцией try/except следующим образом:374375```python376try:377 res = await shield(something())378except CancelledError:379 res = None380```381382Устарело с версии 3.8, будет удалено в версии 3.10: Параметр *loop*.383384## [Тайм-ауты](https://python-all.ru/3.8/library/asyncio-task.html#id8)385386#### `coroutine asyncio.wait_for(aw, timeout, *, loop=None)`387388Ожидает завершения *aw* [ожидаемого объекта](https://python-all.ru/3.8/library/asyncio-task.html#asyncio-awaitables) с таймаутом.389390Если *aw* является корутиной, она автоматически планируется как задача.391392*timeout* может быть либо `None`, либо числом с плавающей запятой или целым числом секунд ожидания. Если *timeout* равно `None`, блокирует выполнение до завершения future.393394Если происходит таймаут, он отменяет задачу и возбуждает [`asyncio.TimeoutError`](https://python-all.ru/3.8/library/asyncio-exceptions.html#asyncio.TimeoutError).395396Чтобы избежать задачи [`cancellation`](https://python-all.ru/3.8/library/asyncio-task.html#asyncio.Task.cancel), оберните её в [`shield()`](https://python-all.ru/3.8/library/asyncio-task.html#asyncio.shield).397398Функция будет ждать, пока future не будет фактически отменён, поэтому общее время ожидания может превысить *тайм-аут*.399400Если ожидание отменяется, future *aw* также отменяется.401402Устарело с версии 3.8, будет удалено в версии 3.10: Параметр *loop*.403404Пример:405406```python407async def eternity():408 # Спать в течение часа409 await asyncio.sleep(3600)410 print('yay!')411412async def main():413 # Ждать не более 1 секунды414 try:415 await asyncio.wait_for(eternity(), timeout=1.0)416 except asyncio.TimeoutError:417 print('timeout!')418419asyncio.run(main())420421# Ожидаемый вывод:422#423# тайм-аут!424```425426Изменено в версии 3.7: Когда *aw* отменяется из-за таймаута, `wait_for` ожидает отмены *aw*. Ранее оно немедленно вызывало [`asyncio.TimeoutError`](https://python-all.ru/3.8/library/asyncio-exceptions.html#asyncio.TimeoutError).427428## [Примитивы ожидания](https://python-all.ru/3.8/library/asyncio-task.html#id9)429430#### `coroutine asyncio.wait(aws, *, loop=None, timeout=None, return_when=ALL_COMPLETED)`431432Запускает [ожидаемые объекты](https://python-all.ru/3.8/library/asyncio-task.html#asyncio-awaitables) в *aws*\\nитерируемом объекте конкурентно и блокируется до выполнения условия, заданного\\n*return\_when*.433434Возвращает два набора задач/future: `(done, pending)`.435436Использование:437438```python439done, pending = await asyncio.wait(aws)440```441442*timeout* (число с плавающей точкой или целое) позволяет указать максимальное время ожидания в секундах перед возвратом результата.443444Обратите внимание, что эта функция не вызывает [`asyncio.TimeoutError`](https://python-all.ru/3.8/library/asyncio-exceptions.html#asyncio.TimeoutError). Объекты Future или задачи, не завершённые к моменту таймаута, просто возвращаются во втором наборе.445446*return\_when* указывает, когда эта функция должна вернуть результат. Это должна быть одна из следующих констант:447448| Константа | Описание |449| --- | --- |450| `FIRST_COMPLETED` | Функция вернёт результат, когда любой future завершится или будет отменён. |451| `FIRST_EXCEPTION` | Функция вернёт результат, когда любой future завершится, возбудив исключение. Если ни один future не возбудит исключение, это эквивалентно `ALL_COMPLETED`. |452| `ALL_COMPLETED` | Функция вернёт результат, когда все future завершатся или будут отменены. |453454В отличие от [`wait_for()`](https://python-all.ru/3.8/library/asyncio-task.html#asyncio.wait_for), `wait()` не отменяет futures при возникновении таймаута.455456Устарело с версии 3.8: Если любой ожидаемый объект в *aws* является корутиной, она автоматически\\nпланируется как задача. Передача объектов-корутин непосредственно в\\n`wait()` устарела, поскольку это приводит к\\n[запутанному поведению](https://python-all.ru/3.8/library/asyncio-task.html#asyncio-example-wait-coroutine).457458Устарело с версии 3.8, будет удалено в версии 3.10: Параметр *loop*.459460> **Примечание**461>462> `wait()` автоматически планирует корутины как задачи и затем возвращает эти неявно созданные объекты задач в `(done, pending)` наборах. Поэтому следующий код не будет работать, как ожидается:463>464> ```python465> async def foo():466> return 42467>468> coro = foo()469> done, pending = await asyncio.wait({coro})470>471> if coro in done:472> # Эта ветка никогда не будет выполнена!473> ```474>475> Вот как можно исправить приведённый выше фрагмент:476>477> ```python478> async def foo():479> return 42480>481> task = asyncio.create_task(foo())482> done, pending = await asyncio.wait({task})483>484> if task in done:485> # Теперь всё будет работать как ожидается.486> ```487488Устарело с версии 3.8: Передача объектов корутины непосредственно в `wait()` устарела.489490#### `asyncio.as_completed(aws, *, loop=None, timeout=None)`491492Запускает [ожидаемые объекты](https://python-all.ru/3.8/library/asyncio-task.html#asyncio-awaitables) из итерируемого *aws* одновременно. Возвращает итератор корутин. Каждую возвращённую корутину можно ожидать, чтобы получить следующий по порядку результат из итерируемого набора оставшихся ожидаемых объектов.493494Вызывает [`asyncio.TimeoutError`](https://python-all.ru/3.8/library/asyncio-exceptions.html#asyncio.TimeoutError), если время ожидания истекает до того, как все Future будут завершены.495496Устарело с версии 3.8, будет удалено в версии 3.10: Параметр *loop*.497498Пример:499500```python501for coro in as_completed(aws):502 earliest_result = await coro503 # ...504```505506## [Планирование из других потоков](https://python-all.ru/3.8/library/asyncio-task.html#id10)507508#### `asyncio.run_coroutine_threadsafe(coro, loop)`509510Отправляет корутину в указанный цикл событий. Потокобезопасно.511512Возвращает [`concurrent.futures.Future`](https://python-all.ru/3.8/library/concurrent.futures.html#concurrent.futures.Future) для ожидания результата из другого потока операционной системы.513514Эта функция предназначена для вызова из другого потока операционной системы, отличного от того, в котором работает цикл событий. Пример:515516```python517# Создать корутину518coro = asyncio.sleep(1, result=3)519520# Отправить корутину в заданный цикл521future = asyncio.run_coroutine_threadsafe(coro, loop)522523# Ожидать результат с необязательным аргументом таймаута524assert future.result(timeout) == 3525```526527Если в корутине возникло исключение, возвращаемый объект Future получит уведомление. Его также можно использовать для отмены задачи в цикле событий:528529```python530try:531 result = future.result(timeout)532except asyncio.TimeoutError:533 print('The coroutine took too long, cancelling the task...')534 future.cancel()535except Exception as exc:536 print(f'The coroutine raised an exception: {exc!r}')537else:538 print(f'The coroutine returned: {result!r}')539```540541См. раздел [concurrency and multithreading](https://python-all.ru/3.8/library/asyncio-dev.html#asyncio-multithreading) документации.542543В отличие от других функций asyncio, эта функция требует явной передачи аргумента *loop* .544545Новое в версии 3.5.1.546547## [Интроспекция](https://python-all.ru/3.8/library/asyncio-task.html#id11)548549#### `asyncio.current_task(loop=None)`550551Возвращает экземпляр текущей выполняющейся [`Task`](https://python-all.ru/3.8/library/asyncio-task.html#asyncio.Task) или `None`, если нет выполняющейся задачи.552553Если *loop* равен `None`, используется [`get_running_loop()`](https://python-all.ru/3.8/library/asyncio-eventloop.html#asyncio.get_running_loop) для получения текущего цикла.554555Добавлено в версии 3.7.556557#### `asyncio.all_tasks(loop=None)`558559Возвращает набор ещё не завершённых объектов [`Task`](https://python-all.ru/3.8/library/asyncio-task.html#asyncio.Task), выполняемых циклом.560561Если *loop* равен `None`, [`get_running_loop()`](https://python-all.ru/3.8/library/asyncio-eventloop.html#asyncio.get_running_loop) используется для получения текущего цикла.562563Добавлено в версии 3.7.564565## [Объект Задачи](https://python-all.ru/3.8/library/asyncio-task.html#id12)566567#### `class asyncio.Task(coro, *, loop=None, name=None)`568569Объект [`Future-like`](https://python-all.ru/3.8/library/asyncio-future.html#asyncio.Future), выполняющий корутину Python [корутину](https://python-all.ru/3.8/library/asyncio-task.html#coroutine). Непотокобезопасный.570571Задачи используются для выполнения корутин в циклах событий. Если корутина ожидает Future, задача приостанавливает выполнение корутины и ждёт завершения Future. Когда Future *завершён*, выполнение обёрнутой корутины возобновляется.572573Циклы событий используют кооперативное планирование: цикл событий выполняет по одной задаче за раз. Пока задача ожидает завершения Future, цикл событий выполняет другие задачи, колбэки или производит операции ввода-вывода.574575Используйте высокоуровневую функцию [`asyncio.create_task()`](https://python-all.ru/3.8/library/asyncio-task.html#asyncio.create_task) для создания задач или низкоуровневые функции [`loop.create_task()`](https://python-all.ru/3.8/library/asyncio-eventloop.html#asyncio.loop.create_task) или [`ensure_future()`](https://python-all.ru/3.8/library/asyncio-future.html#asyncio.ensure_future). Ручное создание экземпляров задач не рекомендуется.576577Чтобы отменить выполняющуюся задачу, используйте метод [`cancel()`](https://python-all.ru/3.8/library/asyncio-task.html#asyncio.Task.cancel). Его вызов приведёт к тому, что задача возбудит исключение [`CancelledError`](https://python-all.ru/3.8/library/asyncio-exceptions.html#asyncio.CancelledError) в обёрнутой корутине. Если во время отмены корутина ожидает объект Future, этот объект Future будет отменён.578579[`cancelled()`](https://python-all.ru/3.8/library/asyncio-task.html#asyncio.Task.cancelled) можно использовать для проверки, была ли задача отменена. Метод возвращает `True`, если обёрнутая корутина не подавила исключение [`CancelledError`](https://python-all.ru/3.8/library/asyncio-exceptions.html#asyncio.CancelledError) и была действительно отменена.580581[`asyncio.Task`](https://python-all.ru/3.8/library/asyncio-task.html#asyncio.Task) наследует от [`Future`](https://python-all.ru/3.8/library/asyncio-future.html#asyncio.Future) все свои API, за исключением [`Future.set_result()`](https://python-all.ru/3.8/library/asyncio-future.html#asyncio.Future.set_result) и [`Future.set_exception()`](https://python-all.ru/3.8/library/asyncio-future.html#asyncio.Future.set_exception).582583Задачи поддерживают модуль [`contextvars`](https://python-all.ru/3.8/library/contextvars.html#module-contextvars). Когда создаётся задача,\\nона копирует текущий контекст и затем выполняет свою\\nкорутину в скопированном контексте.584585Изменено в версии 3.7: Добавлена поддержка модуля [`contextvars`](https://python-all.ru/3.8/library/contextvars.html#module-contextvars).586587Изменено в версии 3.8: Добавлен параметр `name`.588589Устарело с версии 3.8, будет удалено в версии 3.10: Параметр *loop*.590591#### `cancel()`592593Запрашивает отмену задачи.594595Обеспечивает выброс исключения [`CancelledError`](https://python-all.ru/3.8/library/asyncio-exceptions.html#asyncio.CancelledError) в обёрнутую корутину на следующем цикле событийного цикла.596597Затем корутина имеет возможность очистить ресурсы или даже отклонить\\nзапрос, подавив исключение с помощью блока [`try`](https://python-all.ru/3.8/reference/compound_stmts.html#try) …\\n… `except CancelledError` … [`finally`](https://python-all.ru/3.8/reference/compound_stmts.html#finally).\\nПоэтому, в отличие от [`Future.cancel()`](https://python-all.ru/3.8/library/asyncio-future.html#asyncio.Future.cancel), [`Task.cancel()`](https://python-all.ru/3.8/library/asyncio-task.html#asyncio.Task.cancel) не\\nгарантирует, что задача будет отменена, хотя полное подавление отмены\\nне является распространённой практикой и активно не рекомендуется.598599Следующий пример показывает, как корутины могут перехватить запрос отмены:600601```python602async def cancel_me():603 print('cancel_me(): before sleep')604605 try:606 # Ждать 1 час607 await asyncio.sleep(3600)608 except asyncio.CancelledError:609 print('cancel_me(): cancel sleep')610 raise611 finally:612 print('cancel_me(): after sleep')613614async def main():615 # Создать задачу "cancel_me"616 task = asyncio.create_task(cancel_me())617618 # Ждать 1 секунду619 await asyncio.sleep(1)620621 task.cancel()622 try:623 await task624 except asyncio.CancelledError:625 print("main(): cancel_me is cancelled now")626627asyncio.run(main())628629# Ожидаемый вывод:630#631# cancel_me(): перед сном632# cancel_me(): отмена сна633# cancel_me(): после сна634# main(): cancel_me теперь отменён635```636637#### `cancelled()`638639Return `True` if the Task is *cancelled*.640641The Task is *cancelled* when the cancellation was requested with [`cancel()`](https://python-all.ru/3.8/library/asyncio-task.html#asyncio.Task.cancel) and the wrapped coroutine propagated the [`CancelledError`](https://python-all.ru/3.8/library/asyncio-exceptions.html#asyncio.CancelledError) exception thrown into it.642643#### `done()`644645Возвращает `True`, если задача *завершена*.646647Задача *завершена*, когда обёрнутая корутина вернула значение, возбудила исключение или задача была отменена.648649#### `result()`650651Возвращает результат задачи.652653Если задача *завершена*, возвращается результат обёрнутой корутины (или, если корутина возбудила исключение, это исключение возбуждается повторно).654655Если задача была *отменена*, этот метод возбуждает исключение [`CancelledError`](https://python-all.ru/3.8/library/asyncio-exceptions.html#asyncio.CancelledError).656657Если результат задачи ещё не доступен, этот метод возбуждает исключение [`InvalidStateError`](https://python-all.ru/3.8/library/asyncio-exceptions.html#asyncio.InvalidStateError).658659#### `exception()`660661Возвращает исключение задачи.662663Если обёрнутая корутина возбудила исключение, возвращается это исключение. Если корутина завершилась нормально, этот метод возвращает `None`.664665Если задача была *отменена*, этот метод возбуждает исключение [`CancelledError`](https://python-all.ru/3.8/library/asyncio-exceptions.html#asyncio.CancelledError).666667Если задача ещё не *завершена*, этот метод возбуждает исключение [`InvalidStateError`](https://python-all.ru/3.8/library/asyncio-exceptions.html#asyncio.InvalidStateError).668669#### `add_done_callback(callback, *, context=None)`670671Добавляет колбэк, который будет выполнен, когда задача *завершена*.672673Этот метод следует использовать только в низкоуровневом коде, основанном на колбэках.674675Подробнее см. в документации [`Future.add_done_callback()`](https://python-all.ru/3.8/library/asyncio-future.html#asyncio.Future.add_done_callback).676677#### `remove_done_callback(callback)`678679Удаляет *колбэк* из списка колбэков.680681Этот метод следует использовать только в низкоуровневом коде, основанном на колбэках.682683Подробнее см. в документации [`Future.remove_done_callback()`](https://python-all.ru/3.8/library/asyncio-future.html#asyncio.Future.remove_done_callback).684685#### `get_stack(*, limit=None)`686687Возвращает список кадров стека для этой задачи.688689Если обёрнутая корутина не завершена, возвращается стек, в котором она приостановлена. Если корутина успешно завершилась или была отменена, возвращается пустой список. Если корутина была завершена исключением, возвращается список кадров трассировки.690691Кадры всегда упорядочены от старых к новым.692693Для приостановленной корутины возвращается только один кадр стека.694695Необязательный аргумент *limit* задаёт максимальное количество возвращаемых кадров; по умолчанию возвращаются все доступные кадры. Порядок возвращаемого списка различается в зависимости от того, возвращается стек или трассировка: возвращаются новейшие кадры стека, но старейшие кадры трассировки. (Это соответствует поведению модуля traceback.)696697#### `print_stack(*, limit=None, file=None)`698699Печатает стек или трассировку для этой задачи.700701Результат аналогичен выводу модуля traceback для кадров, полученных с помощью [`get_stack()`](https://python-all.ru/3.8/library/asyncio-task.html#asyncio.Task.get_stack).702703Аргумент *limit* передаётся непосредственно в [`get_stack()`](https://python-all.ru/3.8/library/asyncio-task.html#asyncio.Task.get_stack).704705Аргумент *file* – это поток ввода-вывода, в который записывается вывод; по умолчанию вывод записывается в [`sys.stderr`](https://python-all.ru/3.8/library/sys.html#sys.stderr).706707#### `get_coro()`708709Возвращает объект корутины, обёрнутый [`Task`](https://python-all.ru/3.8/library/asyncio-task.html#asyncio.Task).710711Новое в версии 3.8.712713#### `get_name()`714715Возвращает имя задачи.716717Если задаче не было явно присвоено имя, стандартная реализация задач asyncio генерирует имя по умолчанию при создании.718719Новое в версии 3.8.720721#### `set_name(value)`722723Устанавливает имя задачи.724725Аргумент *value* может быть любым объектом, который затем преобразуется в строку.726727В стандартной реализации задач имя будет видно в [`repr()`](https://python-all.ru/3.8/library/functions.html#repr)-выводе объекта задачи.728729Новое в версии 3.8.730731#### `classmethod all_tasks(loop=None)`732733Возвращает набор всех задач для цикла событий.734735По умолчанию возвращаются все задачи для текущего цикла событий. Если *loop* равен `None`, для получения текущего цикла используется функция [`get_event_loop()`](https://python-all.ru/3.8/library/asyncio-eventloop.html#asyncio.get_event_loop).736737Устарело с версии 3.7, будет удалено в версии 3.9: Не вызывайте это как метод задачи. Вместо этого используйте функцию [`asyncio.all_tasks()`](https://python-all.ru/3.8/library/asyncio-task.html#asyncio.all_tasks).738739#### `classmethod current_task(loop=None)`740741Возвращает текущую выполняющуюся задачу или `None`.742743Если *loop* равен `None`, для получения текущего цикла используется функция [`get_event_loop()`](https://python-all.ru/3.8/library/asyncio-eventloop.html#asyncio.get_event_loop).744745Устарело с версии 3.7, будет удалено в версии 3.9: Не вызывайте это как метод задачи. Используйте функцию [`asyncio.current_task()`](https://python-all.ru/3.8/library/asyncio-task.html#asyncio.current_task).746747## [Корутины на основе генераторов](https://python-all.ru/3.8/library/asyncio-task.html#id13)748749> **Примечание**750>751> Поддержка корутин на основе генераторов **устарела** и запланирована к удалению в Python 3.10.752753Корутины на основе генераторов предшествуют синтаксису async/await. Они представляют собой генераторы Python, использующие выражения `yield from` для ожидания Future и других корутин.754755Корутины на основе генераторов следует декорировать с помощью [`@asyncio.coroutine`](https://python-all.ru/3.8/library/asyncio-task.html#asyncio.coroutine), хотя это не требуется.756757#### `@asyncio.coroutine`758759Декоратор для пометки корутин на основе генераторов.760761Этот декоратор позволяет старым корутинам на основе генераторов быть совместимыми с кодом async/await:762763```python764@asyncio.coroutine765def old_style_coroutine():766 yield from asyncio.sleep(1)767768async def main():769 await old_style_coroutine()770```771772Этот декоратор не следует использовать для [`async def`](https://python-all.ru/3.8/reference/compound_stmts.html#async-def) корутин.773774Устарело с версии 3.8, будет удалено в версии 3.10: Используйте [`async def`](https://python-all.ru/3.8/reference/compound_stmts.html#async-def) вместо этого.775776#### `asyncio.iscoroutine(obj)`777778Возвращает `True`, если *obj* является [объектом корутины](https://python-all.ru/3.8/library/asyncio-task.html#coroutine).779780Этот метод отличается от [`inspect.iscoroutine()`](https://python-all.ru/3.8/library/inspect.html#inspect.iscoroutine) тем, что возвращает `True` для корутин на основе генераторов.781782#### `asyncio.iscoroutinefunction(func)`783784Возвращает `True`, если *func* является [корутинной функцией](https://python-all.ru/3.8/library/asyncio-task.html#coroutine).785786Этот метод отличается от [`inspect.iscoroutinefunction()`](https://python-all.ru/3.8/library/inspect.html#inspect.iscoroutinefunction) тем, что возвращает `True` для корутинных функций на основе генераторов, декорированных с помощью [`@coroutine`](https://python-all.ru/3.8/library/asyncio-task.html#asyncio.coroutine).787