> **Источник:** https://python-all.ru/3.8/library/asyncio-task.html
>
> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.

---

# Корутины и задачи

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

- [Корутины](https://python-all.ru/3.8/library/asyncio-task.html#coroutines)
- [Ожидаемые объекты](https://python-all.ru/3.8/library/asyncio-task.html#awaitables)
- [Запуск asyncio-программы](https://python-all.ru/3.8/library/asyncio-task.html#running-an-asyncio-program)
- [Создание задач](https://python-all.ru/3.8/library/asyncio-task.html#creating-tasks)
- [Приостановка выполнения](https://python-all.ru/3.8/library/asyncio-task.html#sleeping)
- [Одновременное выполнение задач](https://python-all.ru/3.8/library/asyncio-task.html#running-tasks-concurrently)
- [Защита от отмены](https://python-all.ru/3.8/library/asyncio-task.html#shielding-from-cancellation)
- [Тайм-ауты](https://python-all.ru/3.8/library/asyncio-task.html#timeouts)
- [Примитивы ожидания](https://python-all.ru/3.8/library/asyncio-task.html#waiting-primitives)
- [Планирование из других потоков](https://python-all.ru/3.8/library/asyncio-task.html#scheduling-from-other-threads)
- [Интроспекция](https://python-all.ru/3.8/library/asyncio-task.html#introspection)
- [Объект задачи](https://python-all.ru/3.8/library/asyncio-task.html#task-object)
- [Корутины на основе генераторов](https://python-all.ru/3.8/library/asyncio-task.html#generator-based-coroutines)

## [Корутины](https://python-all.ru/3.8/library/asyncio-task.html#id1)

[Корутины](https://python-all.ru/3.8/glossary.html#term-coroutine), объявленные с помощью синтаксиса async/await, являются предпочтительным способом написания asyncio-приложений. Например, следующий фрагмент кода (требуется Python 3.7+) выводит «hello», ждёт 1 секунду, а затем выводит «world»:

```python
>>> import asyncio

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

>>> asyncio.run(main())
hello
world
```

Обратите внимание, что простой вызов корутины не запланирует её выполнение:

```python
>>> main()
<coroutine object main at 0x1053bb7c8>
```

Для фактического запуска корутины asyncio предоставляет три основных механизма:

- Функция [`asyncio.run()`](https://python-all.ru/3.8/library/asyncio-task.html#asyncio.run) для запуска точки входа верхнего уровня – функции «main()» (см. пример выше.)
- Ожидание корутины. Следующий фрагмент кода выведет «hello» после ожидания в 1 секунду, а затем выведет «world» после ожидания *ещё* 2 секунд:

  ```python
  import asyncio
  import time

  async def say_after(delay, what):
      await asyncio.sleep(delay)
      print(what)

  async def main():
      print(f"started at {time.strftime('%X')}")

      await say_after(1, 'hello')
      await say_after(2, 'world')

      print(f"finished at {time.strftime('%X')}")

  asyncio.run(main())
  ```

  Ожидаемый вывод:

  ```python
  started at 17:13:52
  hello
  world
  finished at 17:13:55
  ```
- Функция [`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).

  Давайте изменим пример выше и запустим две `say_after` корутины *параллельно*:

  ```python
  async def main():
      task1 = asyncio.create_task(
          say_after(1, 'hello'))

      task2 = asyncio.create_task(
          say_after(2, 'world'))

      print(f"started at {time.strftime('%X')}")

      # Ожидать завершения обеих задач (должно занять
      # около 2 секунд).
      await task1
      await task2

      print(f"finished at {time.strftime('%X')}")
  ```

  Обратите внимание, что ожидаемый вывод теперь показывает, что фрагмент выполняется на 1 секунду быстрее, чем раньше:

  ```python
  started at 17:14:32
  hello
  world
  finished at 17:14:34
  ```

## [Ожидаемые объекты](https://python-all.ru/3.8/library/asyncio-task.html#id2)

Говорят, что объект является **ожидаемым** объектом, если его можно использовать в выражении [`await`](https://python-all.ru/3.8/reference/expressions.html#await). Многие API asyncio предназначены для принятия ожидаемых объектов.

Существует три основных типа *ожидаемых* объектов: **корутины**, **задачи** и **future**.

Корутины

Корутины Python являются *ожидаемыми объектами*, а значит, их можно ожидать из других корутин:

```python
import asyncio

async def nested():
    return 42

async def main():
    # Если просто вызвать "nested()", ничего не произойдет.
    # Создается объект корутины, но он не ожидается,
    # поэтому он *вообще не выполнится*.
    nested()

    # Давайте поступим иначе и теперь ожидаем его:
    print(await nested())  # выведет "42".

asyncio.run(main())
```

> **Важно**
>
> В данной документации термин «корутина» может использоваться для двух тесно связанных понятий:
>
> - *корутинная функция*: функция [`async def`](https://python-all.ru/3.8/reference/compound_stmts.html#async-def);
> - *объект корутины*: объект, возвращаемый при вызове *корутинной функции*.

asyncio также поддерживает устаревшие [корутины на основе генераторов](https://python-all.ru/3.8/library/asyncio-task.html#asyncio-generator-based-coro).

Задачи

*Задачи* используются для планирования корутин *параллельно*.

Когда корутина обёрнута в *задачу* с помощью таких функций, как [`asyncio.create_task()`](https://python-all.ru/3.8/library/asyncio-task.html#asyncio.create_task), корутина автоматически планируется к скорому выполнению:

```python
import asyncio

async def nested():
    return 42

async def main():
    # Запланировать выполнение nested() вскоре конкурентно
    # с "main()".
    task = asyncio.create_task(nested())

    # "задача" теперь можно использовать для отмены "nested()" или
    # можно просто применить await, чтобы дождаться завершения:
    await task

asyncio.run(main())
```

Future

[`Future`](https://python-all.ru/3.8/library/asyncio-future.html#asyncio.Future) – это специальный **низкоуровневый** ожидаемый объект, который представляет **конечный результат** асинхронной операции.

Когда объект Future *ожидается*, это означает, что корутина будет ожидать, пока Future не будет разрешён в каком-то другом месте.

Объекты Future в asyncio необходимы для того, чтобы код, основанный на колбэках, мог использоваться с async/await.

Обычно **нет необходимости** создавать объекты Future в коде уровня приложения.

Объекты Future, иногда предоставляемые библиотеками и некоторыми API asyncio, можно ожидать (await):

```python
async def main():
    await function_that_returns_a_future_object()

    # это также допустимо:
    await asyncio.gather(
        function_that_returns_a_future_object(),
        some_python_coroutine()
    )
```

Хороший пример низкоуровневой функции, возвращающей объект Future – [`loop.run_in_executor()`](https://python-all.ru/3.8/library/asyncio-eventloop.html#asyncio.loop.run_in_executor).

## [Запуск программы asyncio](https://python-all.ru/3.8/library/asyncio-task.html#id3)

#### `asyncio.run(coro, *, debug=False)`

Выполняет [корутину](https://python-all.ru/3.8/glossary.html#term-coroutine) *coro* и возвращает результат.

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

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

Если *debug* равно `True`, цикл событий будет запущен в режиме отладки.

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

Пример:

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

asyncio.run(main())
```

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

> **Примечание**
>
> Исходный код `asyncio.run()` можно найти в\\n[Lib/asyncio/runners.py](https://python-all.ru/src/3.8/Lib/asyncio/runners.py).

## [Создание задач](https://python-all.ru/3.8/library/asyncio-task.html#id4)

#### `asyncio.create_task(coro, *, name=None)`

Wrap 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.

Если *name* не равен `None`, он устанавливается как имя задачи с помощью [`Task.set_name()`](https://python-all.ru/3.8/library/asyncio-task.html#asyncio.Task.set_name).

Задача выполняется в цикле, возвращаемом [`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) возбуждается, если в текущем потоке нет запущенного цикла.

Эта функция была **добавлена в Python 3.7**. До Python 3.7 вместо неё можно использовать низкоуровневую функцию [`asyncio.ensure_future()`](https://python-all.ru/3.8/library/asyncio-future.html#asyncio.ensure_future):

```python
async def coro():
    ...

# В Python 3.7+
task = asyncio.create_task(coro())
...

# Это работает во всех версиях Python, но менее читаемо
task = asyncio.ensure_future(coro())
...
```

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

Изменено в версии 3.8: Добавлен параметр `name`.

## [Ожидание](https://python-all.ru/3.8/library/asyncio-task.html#id5)

#### `coroutine asyncio.sleep(delay, result=None, *, loop=None)`

Приостанавливает выполнение на *delay* секунд.

Если *result* указан, он возвращается вызывающей стороне после завершения корутины.

`sleep()` всегда приостанавливает текущую задачу, позволяя выполняться другим задачам.

Устарело с версии 3.8, будет удалено в версии 3.10: Параметр *loop*.

Пример корутины, выводящей текущую дату каждую секунду в течение 5 секунд:

```python
import asyncio
import datetime

async def display_date():
    loop = asyncio.get_running_loop()
    end_time = loop.time() + 5.0
    while True:
        print(datetime.datetime.now())
        if (loop.time() + 1.0) >= end_time:
            break
        await asyncio.sleep(1)

asyncio.run(display_date())
```

## [Одновременный запуск задач](https://python-all.ru/3.8/library/asyncio-task.html#id6)

#### `awaitable asyncio.gather(*aws, loop=None, return_exceptions=False)`

Выполняет [ожидаемые объекты](https://python-all.ru/3.8/library/asyncio-task.html#asyncio-awaitables) из последовательности *aws* *одновременно*.

Если любой ожидаемый объект из *aws* является корутиной, он автоматически планируется как задача.

Если все ожидаемые объекты завершены успешно, результатом является сводный список возвращённых значений. Порядок значений результата соответствует порядку ожидаемых объектов в *aws*.

Если *return\_exceptions* равно `False` (по умолчанию), первое возбуждённое исключение немедленно распространяется на задачу, ожидающую `gather()`. Остальные ожидаемые объекты в последовательности *aws* **не будут отменены** и продолжат выполнение.

Если *return\_exceptions* равно `True`, исключения обрабатываются так же, как успешные результаты, и объединяются в списке результатов.

Если `gather()` *отменён*, все переданные ожидаемые объекты (которые ещё не завершились) также *отменяются*.

Если любая задача или Future из последовательности *aws* *отменена*, это рассматривается так, как если бы она возбудила [`CancelledError`](https://python-all.ru/3.8/library/asyncio-exceptions.html#asyncio.CancelledError) – вызов `gather()` в этом случае **не** отменяется. Это сделано для предотвращения ситуации, когда отмена одной переданной задачи или Future приводит к отмене других задач или Future.

Устарело с версии 3.8, будет удалено в версии 3.10: Параметр *loop*.

Пример:

```python
import asyncio

async def factorial(name, number):
    f = 1
    for i in range(2, number + 1):
        print(f"Task {name}: Compute factorial({i})...")
        await asyncio.sleep(1)
        f *= i
    print(f"Task {name}: factorial({number}) = {f}")

async def main():
    # Запланировать три вызова *конкурентно*:
    await asyncio.gather(
        factorial("A", 2),
        factorial("B", 3),
        factorial("C", 4),
    )

asyncio.run(main())

# Ожидаемый вывод:
#
#     Задача A: вычислить factorial(2)...
#     Задача B: вычислить factorial(2)...
#     Задача C: вычислить factorial(2)...
#     Задача A: factorial(2) = 2
#     Задача B: вычислить factorial(3)...
#     Задача C: вычислить factorial(3)...
#     Задача B: factorial(3) = 6
#     Задача C: вычислить factorial(4)...
#     Задача C: factorial(4) = 24
```

> **Примечание**
>
> Если *return\_exceptions* равно False, отмена gather() после того, как он был помечен как завершённый, не отменит ни один из переданных ожидаемых объектов. Например, gather может быть помечен как завершённый после распространения исключения вызывающему коду; следовательно, вызов `gather.cancel()` после перехвата исключения (возбуждённого одним из ожидаемых объектов) из gather не отменит другие ожидаемые объекты.

Изменено в версии 3.7: Если сам *gather* отменён, отмена распространяется независимо от *return\_exceptions*.

## [Защита от отмены](https://python-all.ru/3.8/library/asyncio-task.html#id7)

#### `awaitable asyncio.shield(aw, *, loop=None)`

Защищает [ожидаемый объект](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).

Если *aw* является корутиной, она автоматически планируется как задача.

Выражение:

```python
res = await shield(something())
```

эквивалентно:

```python
res = await something()
```

*За исключением* того, что если содержащая его корутина отменяется, задача, выполняющаяся в `something()`, не отменяется. С точки зрения `something()` отмена не произошла. Хотя её вызывающий код всё ещё отменён, поэтому выражение «await» по-прежнему возбуждает [`CancelledError`](https://python-all.ru/3.8/library/asyncio-exceptions.html#asyncio.CancelledError).

Если `something()` отменяется другими средствами (т.е. изнутри самой себя), это также отменит `shield()`.

Если требуется полностью игнорировать отмену (не рекомендуется), функцию `shield()` следует комбинировать с конструкцией try/except следующим образом:

```python
try:
    res = await shield(something())
except CancelledError:
    res = None
```

Устарело с версии 3.8, будет удалено в версии 3.10: Параметр *loop*.

## [Тайм-ауты](https://python-all.ru/3.8/library/asyncio-task.html#id8)

#### `coroutine asyncio.wait_for(aw, timeout, *, loop=None)`

Ожидает завершения *aw* [ожидаемого объекта](https://python-all.ru/3.8/library/asyncio-task.html#asyncio-awaitables) с таймаутом.

Если *aw* является корутиной, она автоматически планируется как задача.

*timeout* может быть либо `None`, либо числом с плавающей запятой или целым числом секунд ожидания. Если *timeout* равно `None`, блокирует выполнение до завершения future.

Если происходит таймаут, он отменяет задачу и возбуждает [`asyncio.TimeoutError`](https://python-all.ru/3.8/library/asyncio-exceptions.html#asyncio.TimeoutError).

Чтобы избежать задачи [`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).

Функция будет ждать, пока future не будет фактически отменён, поэтому общее время ожидания может превысить *тайм-аут*.

Если ожидание отменяется, future *aw* также отменяется.

Устарело с версии 3.8, будет удалено в версии 3.10: Параметр *loop*.

Пример:

```python
async def eternity():
    # Спать в течение часа
    await asyncio.sleep(3600)
    print('yay!')

async def main():
    # Ждать не более 1 секунды
    try:
        await asyncio.wait_for(eternity(), timeout=1.0)
    except asyncio.TimeoutError:
        print('timeout!')

asyncio.run(main())

# Ожидаемый вывод:
#
#     тайм-аут!
```

Изменено в версии 3.7: Когда *aw* отменяется из-за таймаута, `wait_for` ожидает отмены *aw*. Ранее оно немедленно вызывало [`asyncio.TimeoutError`](https://python-all.ru/3.8/library/asyncio-exceptions.html#asyncio.TimeoutError).

## [Примитивы ожидания](https://python-all.ru/3.8/library/asyncio-task.html#id9)

#### `coroutine asyncio.wait(aws, *, loop=None, timeout=None, return_when=ALL_COMPLETED)`

Запускает [ожидаемые объекты](https://python-all.ru/3.8/library/asyncio-task.html#asyncio-awaitables) в *aws*\\nитерируемом объекте конкурентно и блокируется до выполнения условия, заданного\\n*return\_when*.

Возвращает два набора задач/future: `(done, pending)`.

Использование:

```python
done, pending = await asyncio.wait(aws)
```

*timeout* (число с плавающей точкой или целое) позволяет указать максимальное время ожидания в секундах перед возвратом результата.

Обратите внимание, что эта функция не вызывает [`asyncio.TimeoutError`](https://python-all.ru/3.8/library/asyncio-exceptions.html#asyncio.TimeoutError). Объекты Future или задачи, не завершённые к моменту таймаута, просто возвращаются во втором наборе.

*return\_when* указывает, когда эта функция должна вернуть результат. Это должна быть одна из следующих констант:

| Константа | Описание |
| --- | --- |
| `FIRST_COMPLETED` | Функция вернёт результат, когда любой future завершится или будет отменён. |
| `FIRST_EXCEPTION` | Функция вернёт результат, когда любой future завершится, возбудив исключение. Если ни один future не возбудит исключение, это эквивалентно `ALL_COMPLETED`. |
| `ALL_COMPLETED` | Функция вернёт результат, когда все future завершатся или будут отменены. |

В отличие от [`wait_for()`](https://python-all.ru/3.8/library/asyncio-task.html#asyncio.wait_for), `wait()` не отменяет futures при возникновении таймаута.

Устарело с версии 3.8: Если любой ожидаемый объект в *aws* является корутиной, она автоматически\\nпланируется как задача. Передача объектов-корутин непосредственно в\\n`wait()` устарела, поскольку это приводит к\\n[запутанному поведению](https://python-all.ru/3.8/library/asyncio-task.html#asyncio-example-wait-coroutine).

Устарело с версии 3.8, будет удалено в версии 3.10: Параметр *loop*.

> **Примечание**
>
> `wait()` автоматически планирует корутины как задачи и затем возвращает эти неявно созданные объекты задач в `(done, pending)` наборах. Поэтому следующий код не будет работать, как ожидается:
>
> ```python
> async def foo():
>     return 42
>
> coro = foo()
> done, pending = await asyncio.wait({coro})
>
> if coro in done:
>     # Эта ветка никогда не будет выполнена!
> ```
>
> Вот как можно исправить приведённый выше фрагмент:
>
> ```python
> async def foo():
>     return 42
>
> task = asyncio.create_task(foo())
> done, pending = await asyncio.wait({task})
>
> if task in done:
>     # Теперь всё будет работать как ожидается.
> ```

Устарело с версии 3.8: Передача объектов корутины непосредственно в `wait()` устарела.

#### `asyncio.as_completed(aws, *, loop=None, timeout=None)`

Запускает [ожидаемые объекты](https://python-all.ru/3.8/library/asyncio-task.html#asyncio-awaitables) из итерируемого *aws* одновременно. Возвращает итератор корутин. Каждую возвращённую корутину можно ожидать, чтобы получить следующий по порядку результат из итерируемого набора оставшихся ожидаемых объектов.

Вызывает [`asyncio.TimeoutError`](https://python-all.ru/3.8/library/asyncio-exceptions.html#asyncio.TimeoutError), если время ожидания истекает до того, как все Future будут завершены.

Устарело с версии 3.8, будет удалено в версии 3.10: Параметр *loop*.

Пример:

```python
for coro in as_completed(aws):
    earliest_result = await coro
    # ...
```

## [Планирование из других потоков](https://python-all.ru/3.8/library/asyncio-task.html#id10)

#### `asyncio.run_coroutine_threadsafe(coro, loop)`

Отправляет корутину в указанный цикл событий. Потокобезопасно.

Возвращает [`concurrent.futures.Future`](https://python-all.ru/3.8/library/concurrent.futures.html#concurrent.futures.Future) для ожидания результата из другого потока операционной системы.

Эта функция предназначена для вызова из другого потока операционной системы, отличного от того, в котором работает цикл событий. Пример:

```python
# Создать корутину
coro = asyncio.sleep(1, result=3)

# Отправить корутину в заданный цикл
future = asyncio.run_coroutine_threadsafe(coro, loop)

# Ожидать результат с необязательным аргументом таймаута
assert future.result(timeout) == 3
```

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

```python
try:
    result = future.result(timeout)
except asyncio.TimeoutError:
    print('The coroutine took too long, cancelling the task...')
    future.cancel()
except Exception as exc:
    print(f'The coroutine raised an exception: {exc!r}')
else:
    print(f'The coroutine returned: {result!r}')
```

См. раздел [concurrency and multithreading](https://python-all.ru/3.8/library/asyncio-dev.html#asyncio-multithreading) документации.

В отличие от других функций asyncio, эта функция требует явной передачи аргумента *loop* .

Новое в версии 3.5.1.

## [Интроспекция](https://python-all.ru/3.8/library/asyncio-task.html#id11)

#### `asyncio.current_task(loop=None)`

Возвращает экземпляр текущей выполняющейся [`Task`](https://python-all.ru/3.8/library/asyncio-task.html#asyncio.Task) или `None`, если нет выполняющейся задачи.

Если *loop* равен `None`, используется [`get_running_loop()`](https://python-all.ru/3.8/library/asyncio-eventloop.html#asyncio.get_running_loop) для получения текущего цикла.

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

#### `asyncio.all_tasks(loop=None)`

Возвращает набор ещё не завершённых объектов [`Task`](https://python-all.ru/3.8/library/asyncio-task.html#asyncio.Task), выполняемых циклом.

Если *loop* равен `None`, [`get_running_loop()`](https://python-all.ru/3.8/library/asyncio-eventloop.html#asyncio.get_running_loop) используется для получения текущего цикла.

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

## [Объект Задачи](https://python-all.ru/3.8/library/asyncio-task.html#id12)

#### `class asyncio.Task(coro, *, loop=None, name=None)`

Объект [`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). Непотокобезопасный.

Задачи используются для выполнения корутин в циклах событий. Если корутина ожидает Future, задача приостанавливает выполнение корутины и ждёт завершения Future. Когда Future *завершён*, выполнение обёрнутой корутины возобновляется.

Циклы событий используют кооперативное планирование: цикл событий выполняет по одной задаче за раз. Пока задача ожидает завершения Future, цикл событий выполняет другие задачи, колбэки или производит операции ввода-вывода.

Используйте высокоуровневую функцию [`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). Ручное создание экземпляров задач не рекомендуется.

Чтобы отменить выполняющуюся задачу, используйте метод [`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 будет отменён.

[`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) и была действительно отменена.

[`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).

Задачи поддерживают модуль [`contextvars`](https://python-all.ru/3.8/library/contextvars.html#module-contextvars). Когда создаётся задача,\\nона копирует текущий контекст и затем выполняет свою\\nкорутину в скопированном контексте.

Изменено в версии 3.7: Добавлена поддержка модуля [`contextvars`](https://python-all.ru/3.8/library/contextvars.html#module-contextvars).

Изменено в версии 3.8: Добавлен параметр `name`.

Устарело с версии 3.8, будет удалено в версии 3.10: Параметр *loop*.

#### `cancel()`

Запрашивает отмену задачи.

Обеспечивает выброс исключения [`CancelledError`](https://python-all.ru/3.8/library/asyncio-exceptions.html#asyncio.CancelledError) в обёрнутую корутину на следующем цикле событийного цикла.

Затем корутина имеет возможность очистить ресурсы или даже отклонить\\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не является распространённой практикой и активно не рекомендуется.

Следующий пример показывает, как корутины могут перехватить запрос отмены:

```python
async def cancel_me():
    print('cancel_me(): before sleep')

    try:
        # Ждать 1 час
        await asyncio.sleep(3600)
    except asyncio.CancelledError:
        print('cancel_me(): cancel sleep')
        raise
    finally:
        print('cancel_me(): after sleep')

async def main():
    # Создать задачу "cancel_me"
    task = asyncio.create_task(cancel_me())

    # Ждать 1 секунду
    await asyncio.sleep(1)

    task.cancel()
    try:
        await task
    except asyncio.CancelledError:
        print("main(): cancel_me is cancelled now")

asyncio.run(main())

# Ожидаемый вывод:
#
#     cancel_me(): перед сном
#     cancel_me(): отмена сна
#     cancel_me(): после сна
#     main(): cancel_me теперь отменён
```

#### `cancelled()`

Return `True` if the Task is *cancelled*.

The 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.

#### `done()`

Возвращает `True`, если задача *завершена*.

Задача *завершена*, когда обёрнутая корутина вернула значение, возбудила исключение или задача была отменена.

#### `result()`

Возвращает результат задачи.

Если задача *завершена*, возвращается результат обёрнутой корутины (или, если корутина возбудила исключение, это исключение возбуждается повторно).

Если задача была *отменена*, этот метод возбуждает исключение [`CancelledError`](https://python-all.ru/3.8/library/asyncio-exceptions.html#asyncio.CancelledError).

Если результат задачи ещё не доступен, этот метод возбуждает исключение [`InvalidStateError`](https://python-all.ru/3.8/library/asyncio-exceptions.html#asyncio.InvalidStateError).

#### `exception()`

Возвращает исключение задачи.

Если обёрнутая корутина возбудила исключение, возвращается это исключение. Если корутина завершилась нормально, этот метод возвращает `None`.

Если задача была *отменена*, этот метод возбуждает исключение [`CancelledError`](https://python-all.ru/3.8/library/asyncio-exceptions.html#asyncio.CancelledError).

Если задача ещё не *завершена*, этот метод возбуждает исключение [`InvalidStateError`](https://python-all.ru/3.8/library/asyncio-exceptions.html#asyncio.InvalidStateError).

#### `add_done_callback(callback, *, context=None)`

Добавляет колбэк, который будет выполнен, когда задача *завершена*.

Этот метод следует использовать только в низкоуровневом коде, основанном на колбэках.

Подробнее см. в документации [`Future.add_done_callback()`](https://python-all.ru/3.8/library/asyncio-future.html#asyncio.Future.add_done_callback).

#### `remove_done_callback(callback)`

Удаляет *колбэк* из списка колбэков.

Этот метод следует использовать только в низкоуровневом коде, основанном на колбэках.

Подробнее см. в документации [`Future.remove_done_callback()`](https://python-all.ru/3.8/library/asyncio-future.html#asyncio.Future.remove_done_callback).

#### `get_stack(*, limit=None)`

Возвращает список кадров стека для этой задачи.

Если обёрнутая корутина не завершена, возвращается стек, в котором она приостановлена. Если корутина успешно завершилась или была отменена, возвращается пустой список. Если корутина была завершена исключением, возвращается список кадров трассировки.

Кадры всегда упорядочены от старых к новым.

Для приостановленной корутины возвращается только один кадр стека.

Необязательный аргумент *limit* задаёт максимальное количество возвращаемых кадров; по умолчанию возвращаются все доступные кадры. Порядок возвращаемого списка различается в зависимости от того, возвращается стек или трассировка: возвращаются новейшие кадры стека, но старейшие кадры трассировки. (Это соответствует поведению модуля traceback.)

#### `print_stack(*, limit=None, file=None)`

Печатает стек или трассировку для этой задачи.

Результат аналогичен выводу модуля traceback для кадров, полученных с помощью [`get_stack()`](https://python-all.ru/3.8/library/asyncio-task.html#asyncio.Task.get_stack).

Аргумент *limit* передаётся непосредственно в [`get_stack()`](https://python-all.ru/3.8/library/asyncio-task.html#asyncio.Task.get_stack).

Аргумент *file* – это поток ввода-вывода, в который записывается вывод; по умолчанию вывод записывается в [`sys.stderr`](https://python-all.ru/3.8/library/sys.html#sys.stderr).

#### `get_coro()`

Возвращает объект корутины, обёрнутый [`Task`](https://python-all.ru/3.8/library/asyncio-task.html#asyncio.Task).

Новое в версии 3.8.

#### `get_name()`

Возвращает имя задачи.

Если задаче не было явно присвоено имя, стандартная реализация задач asyncio генерирует имя по умолчанию при создании.

Новое в версии 3.8.

#### `set_name(value)`

Устанавливает имя задачи.

Аргумент *value* может быть любым объектом, который затем преобразуется в строку.

В стандартной реализации задач имя будет видно в [`repr()`](https://python-all.ru/3.8/library/functions.html#repr)-выводе объекта задачи.

Новое в версии 3.8.

#### `classmethod all_tasks(loop=None)`

Возвращает набор всех задач для цикла событий.

По умолчанию возвращаются все задачи для текущего цикла событий. Если *loop* равен `None`, для получения текущего цикла используется функция [`get_event_loop()`](https://python-all.ru/3.8/library/asyncio-eventloop.html#asyncio.get_event_loop).

Устарело с версии 3.7, будет удалено в версии 3.9: Не вызывайте это как метод задачи. Вместо этого используйте функцию [`asyncio.all_tasks()`](https://python-all.ru/3.8/library/asyncio-task.html#asyncio.all_tasks).

#### `classmethod current_task(loop=None)`

Возвращает текущую выполняющуюся задачу или `None`.

Если *loop* равен `None`, для получения текущего цикла используется функция [`get_event_loop()`](https://python-all.ru/3.8/library/asyncio-eventloop.html#asyncio.get_event_loop).

Устарело с версии 3.7, будет удалено в версии 3.9: Не вызывайте это как метод задачи. Используйте функцию [`asyncio.current_task()`](https://python-all.ru/3.8/library/asyncio-task.html#asyncio.current_task).

## [Корутины на основе генераторов](https://python-all.ru/3.8/library/asyncio-task.html#id13)

> **Примечание**
>
> Поддержка корутин на основе генераторов **устарела** и запланирована к удалению в Python 3.10.

Корутины на основе генераторов предшествуют синтаксису async/await. Они представляют собой генераторы Python, использующие выражения `yield from` для ожидания Future и других корутин.

Корутины на основе генераторов следует декорировать с помощью [`@asyncio.coroutine`](https://python-all.ru/3.8/library/asyncio-task.html#asyncio.coroutine), хотя это не требуется.

#### `@asyncio.coroutine`

Декоратор для пометки корутин на основе генераторов.

Этот декоратор позволяет старым корутинам на основе генераторов быть совместимыми с кодом async/await:

```python
@asyncio.coroutine
def old_style_coroutine():
    yield from asyncio.sleep(1)

async def main():
    await old_style_coroutine()
```

Этот декоратор не следует использовать для [`async def`](https://python-all.ru/3.8/reference/compound_stmts.html#async-def) корутин.

Устарело с версии 3.8, будет удалено в версии 3.10: Используйте [`async def`](https://python-all.ru/3.8/reference/compound_stmts.html#async-def) вместо этого.

#### `asyncio.iscoroutine(obj)`

Возвращает `True`, если *obj* является [объектом корутины](https://python-all.ru/3.8/library/asyncio-task.html#coroutine).

Этот метод отличается от [`inspect.iscoroutine()`](https://python-all.ru/3.8/library/inspect.html#inspect.iscoroutine) тем, что возвращает `True` для корутин на основе генераторов.

#### `asyncio.iscoroutinefunction(func)`

Возвращает `True`, если *func* является [корутинной функцией](https://python-all.ru/3.8/library/asyncio-task.html#coroutine).

Этот метод отличается от [`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).
