asyncio-task.md
1> **Источник:** https://python-all.ru/3.4/library/asyncio-task.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 18.5.3. Задачи и корутины89## 18.5.3.1. Корутины1011Корутина – это генератор, который следует определённым соглашениям. Для целей документации все корутины следует декорировать с помощью `@asyncio.coroutine`, но это не может быть строго обязательным.1213Корутины используют синтаксис `yield from`, введённый в [**PEP 380**](https://python-all.ru/3.4/library/asyncio-task.html), вместо оригинального синтаксиса `yield`.1415Слово «корутина», как и слово «генератор», используется для двух различных (хотя и связанных) понятий:1617- Функция, которая определяет корутину (определение функции, декорированное с помощью `@asyncio.coroutine`). Если требуется уточнение, мы будем называть её *корутинной функцией* ([`iscoroutinefunction()`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.iscoroutinefunction) возвращает `True`).18- Объект, полученный вызовом корутинной функции. Этот объект представляет вычисление или операцию ввода-вывода (обычно комбинацию), которая когда-нибудь завершится. Если требуется уточнение, мы будем называть его *корутинным объектом* ([`iscoroutine()`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.iscoroutine) возвращает `True`).1920Что может делать корутина:2122- `result = yield from future` – приостанавливает корутину, пока future не будет завершён, затем возвращает результат future или возбуждает исключение, которое будет распространено. (Если future отменён, будет возбуждено исключение `CancelledError`.) Заметьте, что задачи являются объектами future, и всё сказанное о future также применимо к задачам.23- `result = yield from корутина` – ожидать завершения другой корутины, чтобы получить результат (или возбудить исключение, которое будет распространено). Выражение `корутина` должно быть *вызовом* другой корутины.24- `return expression` – передать результат корутине, которая ожидает данную с помощью `yield from`.25- `raise исключение` – возбудить исключение в корутине, которая ожидает данную с помощью `yield from`.2627Вызов корутины не запускает её код – это всего лишь генератор, и объект корутины, возвращаемый вызовом, на самом деле является объектом генератора, который ничего не делает, пока по нему не пройти итерацией. В случае объекта корутины есть два основных способа запустить её выполнение: вызвать `yield from корутина` из другой корутины (если другая корутина уже выполняется!), или запланировать её выполнение с помощью функции [`async()`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.async) или метода [`BaseEventLoop.create_task()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.create_task).2829Корутины (и задачи) могут выполняться только когда запущен цикл событий.3031#### `@asyncio.coroutine`3233Декоратор для пометки корутин.3435Если корутина не была использована с yield from до её уничтожения, в журнал выводится сообщение об ошибке. См. [*Обнаружение корутин, которые никогда не были запланированы*](https://python-all.ru/3.4/library/asyncio-dev.html#asyncio-coroutine-not-scheduled).3637> **Примечание**38>39> В этой документации некоторые методы описаны как корутины, даже если они являются обычными функциями Python, возвращающими [`Future`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.Future). Это сделано намеренно, чтобы сохранить свободу изменения реализации этих функций в будущем. Если такую функцию необходимо использовать в коде в стиле колбэков, оберните её результат с помощью [`async()`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.async).4041### 18.5.3.1.1. Пример: корутина Hello World4243Пример корутины, выводящей `"Hello World"`:4445```python46import asyncio4748@asyncio.coroutine49def hello_world():50 print("Hello World!")5152loop = asyncio.get_event_loop()53# Блокирующий вызов, который возвращает управление после завершения корутины hello_world()54loop.run_until_complete(hello_world())55loop.close()56```5758> **См. также**59>60> Пример [*Hello World с call\_soon()*](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio-hello-world-callback) использует метод [`BaseEventLoop.call_soon()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.call_soon) для планирования колбэка.6162### 18.5.3.1.2. Пример: корутина, показывающая текущую дату6364Пример корутины, выводящей текущую дату каждую секунду в течение 5 секунд с помощью функции [`sleep()`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.sleep):6566```python67import asyncio68import datetime6970@asyncio.coroutine71def display_date(loop):72 end_time = loop.time() + 5.073 while True:74 print(datetime.datetime.now())75 if (loop.time() + 1.0) >= end_time:76 break77 yield from asyncio.sleep(1)7879loop = asyncio.get_event_loop()80# Блокирующий вызов, который возвращает управление после завершения корутины display_date()81loop.run_until_complete(display_date(loop))82loop.close()83```8485> **См. также**86>87> Пример [*display the current date with call\_later()*](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio-date-callback) использует колбэк с методом [`BaseEventLoop.call_later()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.call_later).8889### 18.5.3.1.3. Пример: цепочка корутин9091Пример соединения корутин в цепочку:9293```python94import asyncio9596@asyncio.coroutine97def compute(x, y):98 print("Compute %s + %s ..." % (x, y))99 yield from asyncio.sleep(1.0)100 return x + y101102@asyncio.coroutine103def print_sum(x, y):104 result = yield from compute(x, y)105 print("%s + %s = %s" % (x, y, result))106107loop = asyncio.get_event_loop()108loop.run_until_complete(print_sum(1, 2))109loop.close()110```111112`compute()` соединяется с `print_sum()`: корутина `print_sum()` ожидает, пока `compute()` не завершится, прежде чем вернуть свой результат.113114Диаграмма последовательности примера:115116117118«Задача» создаётся методом [`BaseEventLoop.run_until_complete()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.run_until_complete), когда он получает объект корутины вместо задачи.119120Диаграмма показывает поток управления, она не описывает точно, как всё работает внутри. Например, корутина sleep создаёт внутренний future, который использует [`BaseEventLoop.call_later()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.call_later), чтобы разбудить задачу через 1 секунду.121122## 18.5.3.2. InvalidStateError123124#### `exception asyncio.InvalidStateError`125126Операция не разрешена в этом состоянии.127128## 18.5.3.3. TimeoutError129130#### `exception asyncio.TimeoutError`131132Операция превысила заданный срок.133134> **Примечание**135>136> Это исключение отличается от встроенного исключения [`TimeoutError`](https://python-all.ru/3.4/library/exceptions.html#TimeoutError)!137138## 18.5.3.4. Future139140#### `class asyncio.Future(*, loop=None)`141142Этот класс *почти* совместим с [`concurrent.futures.Future`](https://python-all.ru/3.4/library/concurrent.futures.html#concurrent.futures.Future).143144Отличия:145146- [`result()`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.Future.result) и [`exception()`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.Future.exception) не принимают аргумент тайм-аута и возбуждают исключение, если future ещё не завершён.147- Колбэки, зарегистрированные с помощью [`add_done_callback()`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.Future.add_done_callback), всегда вызываются через метод цикла событий [`call_soon_threadsafe()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.call_soon_threadsafe).148- Этот класс несовместим с функциями [`wait()`](https://python-all.ru/3.4/library/concurrent.futures.html#concurrent.futures.wait) и [`as_completed()`](https://python-all.ru/3.4/library/concurrent.futures.html#concurrent.futures.as_completed) из пакета [`concurrent.futures`](https://python-all.ru/3.4/library/concurrent.futures.html#module-concurrent.futures).149150This class is [*не является потокобезопасным*](https://python-all.ru/3.4/library/asyncio-dev.html#asyncio-multithreading).151152#### `cancel()`153154Отменить future и запланировать вызов колбэков.155156Если future уже завершён или отменён, возвращает `False`. В противном случае меняет состояние future на отменён, планирует колбэки и возвращает `True`.157158#### `cancelled()`159160Возвращает `True`, если future отменён.161162#### `done()`163164Возвращает True, если future завершён.165166«Завершён» означает либо наличие результата или исключения, либо то, что future был отменён.167168#### `result()`169170Вернуть результат, который представляет этот future.171172Если future отменён, возбуждает `CancelledError`. Если результат future ещё недоступен, возбуждает [`InvalidStateError`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.InvalidStateError). Если future завершён и имеет установленное исключение, это исключение возбуждается.173174#### `exception()`175176Вернуть исключение, которое было установлено для этого future.177178Исключение (или `None`, если исключение не было установлено) возвращается только в том случае, если future завершён. Если future отменён, возбуждает `CancelledError`. Если future ещё не завершён, возбуждает [`InvalidStateError`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.InvalidStateError).179180#### `add_done_callback(fn)`181182Добавить колбэк, который будет вызван, когда future станет завершённым.183184Колбэк вызывается с одним аргументом – объектом future. Если future уже завершён на момент вызова, колбэк планируется с помощью [`call_soon()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.call_soon).185186[*Используйте functools.partial для передачи параметров в колбэк*](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio-pass-keywords). Например, `fut.add_done_callback(functools.partial(print, "Future:", flush=True))` вызовет `print("Future:", fut, flush=True)`.187188#### `remove_done_callback(fn)`189190Удалить все экземпляры колбэка из списка «вызвать при завершении».191192Возвращает количество удалённых колбэков.193194#### `set_result(result)`195196Пометить future как завершённый и установить его результат.197198Если future уже завершён при вызове этого метода, возбуждает [`InvalidStateError`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.InvalidStateError).199200#### `set_exception(exception)`201202Пометить future как завершённый и установить исключение.203204Если future уже завершён при вызове этого метода, возбуждает [`InvalidStateError`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.InvalidStateError).205206### 18.5.3.4.1. Пример: Future с run\_until\_complete()207208Пример, объединяющий [`Future`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.Future) и [*корутинную функцию*](https://python-all.ru/3.4/library/asyncio-task.html#coroutine):209210```python211import asyncio212213@asyncio.coroutine214def slow_operation(future):215 yield from asyncio.sleep(1)216 future.set_result('Future is done!')217218loop = asyncio.get_event_loop()219future = asyncio.Future()220asyncio.ensure_future(slow_operation(future))221loop.run_until_complete(future)222print(future.result())223loop.close()224```225226Корутинная функция отвечает за вычисление (которое занимает 1 секунду) и сохраняет результат в future. Метод [`run_until_complete()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.run_until_complete) ожидает завершения future.227228> **Примечание**229>230> Метод [`run_until_complete()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.run_until_complete) внутренне использует метод [`add_done_callback()`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.Future.add_done_callback) для получения уведомления о завершении future.231232### 18.5.3.4.2. Пример: Future с run\_forever()233234Предыдущий пример можно записать иначе, используя метод [`Future.add_done_callback()`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.Future.add_done_callback) для явного описания потока управления:235236```python237import asyncio238239@asyncio.coroutine240def slow_operation(future):241 yield from asyncio.sleep(1)242 future.set_result('Future is done!')243244def got_result(future):245 print(future.result())246 loop.stop()247248loop = asyncio.get_event_loop()249future = asyncio.Future()250asyncio.ensure_future(slow_operation(future))251future.add_done_callback(got_result)252try:253 loop.run_forever()254finally:255 loop.close()256```257258В этом примере future используется для связывания `slow_operation()` с `got_result()`: когда `slow_operation()` завершается, `got_result()` вызывается с результатом.259260## 18.5.3.5. Задача261262#### `class asyncio.Task(coro, *, loop=None)`263264Планирует выполнение [*корутины*](https://python-all.ru/3.4/library/asyncio-task.html#coroutine): оборачивает её в future. Задача (Task) является подклассом [`Future`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.Future).265266Задача отвечает за выполнение объекта корутины в цикле событий. Если обёрнутая корутина выполняет yield из future, задача приостанавливает выполнение обёрнутой корутины и ожидает завершения future. Когда future завершён, выполнение обёрнутой корутины возобновляется с результатом или исключением future.267268Циклы событий используют кооперативное планирование: цикл событий запускает только одну задачу за раз. Другие задачи могут выполняться параллельно, если другие циклы событий работают в разных потоках. Пока задача ожидает завершения future, цикл событий выполняет новую задачу.269270Отмена задачи отличается от отмены future. Вызов [`cancel()`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.Task.cancel) вызовет `CancelledError` в обёрнутой корутине. [`cancelled()`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.Future.cancelled) возвращает `True` только если обёрнутая корутина не перехватила исключение `CancelledError`, или возбудила исключение `CancelledError`.271272Если ожидающая задача уничтожается, выполнение её обёрнутой [*корутины*](https://python-all.ru/3.4/library/asyncio-task.html#coroutine) не завершилось. Вероятно, это ошибка, и в журнал записывается предупреждение: см. [*Ожидающая задача уничтожена*](https://python-all.ru/3.4/library/asyncio-dev.html#asyncio-pending-task-destroyed).273274Don’t directly create [`Task`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.Task) instances: use the [`async()`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.async) function or the [`BaseEventLoop.create_task()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.create_task) method.275276This class is [*не является потокобезопасным*](https://python-all.ru/3.4/library/asyncio-dev.html#asyncio-multithreading).277278#### `classmethod all_tasks(loop=None)`279280Возвращает набор всех задач для цикла событий.281282По умолчанию возвращаются все задачи для текущего цикла событий.283284#### `classmethod current_task(loop=None)`285286Возвращает текущую выполняющуюся задачу в цикле событий или `None`.287288По умолчанию возвращается текущая задача для текущего цикла событий.289290`None` возвращается при вызове не в контексте [`задачи`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.Task).291292#### `cancel()`293294Запрашивает отмену этой задачи.295296Эта функция обеспечивает, что `CancelledError` будет выброшен в обёрнутую корутину на следующем цикле событий. Затем корутина может выполнить очистку или даже отклонить запрос с помощью try/except/finally.297298В отличие от [`Future.cancel()`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.Future.cancel), этот метод не гарантирует, что задача будет отменена: исключение может быть перехвачено и обработано, что отложит отмену задачи или предотвратит её полностью. Задача также может вернуть значение или вызвать другое исключение.299300Сразу после вызова этого метода [`cancelled()`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.Future.cancelled) не будет возвращать `True` (если только задача не была уже отменена). Задача будет помечена как отменённая, когда обёрнутая корутина завершится с исключением `CancelledError` (даже если [`cancel()`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.Task.cancel) не был вызван).301302#### `get_stack(*, limit=None)`303304Возвращает список фреймов стека для корутины этой задачи.305306Если корутина не завершена, возвращается стек, в котором она приостановлена. Если корутина успешно завершилась или была отменена, возвращается пустой список. Если корутина была прервана исключением, возвращается список фреймов traceback.307308Кадры всегда упорядочены от старых к новым.309310Необязательный параметр limit задаёт максимальное количество возвращаемых фреймов; по умолчанию возвращаются все доступные фреймы. Его значение различается в зависимости от того, возвращается стек или traceback: возвращаются самые новые фреймы стека, но самые старые фреймы traceback. (Это соответствует поведению модуля traceback.)311312По независящим от нас причинам для приостановленной корутины возвращается только один фрейм стека.313314#### `print_stack(*, limit=None, file=None)`315316Выводит стек или traceback для корутины этой задачи.317318Вывод похож на вывод модуля traceback для фреймов, полученных с помощью get\_stack(). Аргумент limit передаётся в get\_stack(). Аргумент file – это I/O поток, в который записывается вывод; по умолчанию вывод записывается в sys.stderr.319320### 18.5.3.5.1. Пример: параллельное выполнение задач321322Пример параллельного выполнения 3 задач (A, B, C):323324```python325import asyncio326327@asyncio.coroutine328def factorial(name, number):329 f = 1330 for i in range(2, number+1):331 print("Task %s: Compute factorial(%s)..." % (name, i))332 yield from asyncio.sleep(1)333 f *= i334 print("Task %s: factorial(%s) = %s" % (name, number, f))335336loop = asyncio.get_event_loop()337tasks = [338 asyncio.ensure_future(factorial("A", 2)),339 asyncio.ensure_future(factorial("B", 3)),340 asyncio.ensure_future(factorial("C", 4))]341loop.run_until_complete(asyncio.wait(tasks))342loop.close()343```344345Вывод:346347```python348Task A: Compute factorial(2)...349Task B: Compute factorial(2)...350Task C: Compute factorial(2)...351Task A: factorial(2) = 2352Task B: Compute factorial(3)...353Task C: Compute factorial(3)...354Task B: factorial(3) = 6355Task C: Compute factorial(4)...356Task C: factorial(4) = 24357```358359Задача автоматически планируется на выполнение при её создании. Цикл событий останавливается, когда все задачи завершены.360361## 18.5.3.6. Функции задач362363> **Примечание**364>365> В функциях ниже необязательный аргумент *loop* позволяет явно указать объект цикла событий, используемый базовой задачей или корутиной. Если он не указан, используется цикл событий по умолчанию.366367#### `asyncio.as_completed(fs, *, loop=None, timeout=None)`368369Возвращает итератор, значения которого (при ожидании) являются [`Future`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.Future) экземплярами.370371Вызывает [`asyncio.TimeoutError`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.TimeoutError), если тайм-аут наступает до завершения всех Future.372373Пример:374375```python376for f in as_completed(fs):377 result = yield from f # Выражение 'yield from' может возбуждать исключение378 # Используйте результат379```380381> **Примечание**382>383> Future `f` не обязательно являются элементами fs.384385#### `asyncio.ensure_future(coro_or_future, *, loop=None)`386387Планирует выполнение [*объекта-корутины*](https://python-all.ru/3.4/library/asyncio-task.html#coroutine): оборачивает его в future. Возвращает объект [`задачи`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.Task).388389Если аргумент является [`Future`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.Future), он возвращается напрямую.390391Новое в версии 3.4.4.392393> **См. также**394>395> Метод [`BaseEventLoop.create_task()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.create_task).396397#### `asyncio.async(coro_or_future, *, loop=None)`398399Устаревший псевдоним [`ensure_future()`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.ensure_future).400401Устарело с версии 3.4.4.402403#### `asyncio.gather(*coros_or_futures, loop=None, return_exceptions=False)`404405Возвращает future, агрегирующий результаты от заданных корутинных объектов или future.406407Все future должны использовать один и тот же цикл событий. Если все задачи выполнены успешно, результатом возвращаемого future будет список результатов (в порядке исходной последовательности, не обязательно в порядке поступления результатов). Если *return\_exceptions* равно True, исключения в задачах трактуются так же, как успешные результаты, и собираются в список результатов; в противном случае первое возникшее исключение будет немедленно распространено на возвращаемый future.408409Отмена: если внешний Future отменён, все дочерние объекты (которые ещё не завершены) также отменяются. Если какой-либо дочерний объект отменён, это рассматривается как если бы он вызвал `CancelledError` – в этом случае внешний Future *не* отменяется. (Это сделано, чтобы отмена одного дочернего объекта не приводила к отмене других.)410411#### `asyncio.iscoroutine(obj)`412413Возвращает `True`, если *obj* является [*объектом-корутиной*](https://python-all.ru/3.4/library/asyncio-task.html#coroutine).414415#### `asyncio.iscoroutinefunction(obj)`416417Возвращает `True`, если *func* является декорированной [*корутинной функцией*](https://python-all.ru/3.4/library/asyncio-task.html#coroutine).418419#### `asyncio.run_coroutine_threadsafe(coro, loop)`420421Отправляет [*корутинный объект*](https://python-all.ru/3.4/library/asyncio-task.html#coroutine) в заданный цикл событий.422423Возвращает [`concurrent.futures.Future`](https://python-all.ru/3.4/library/concurrent.futures.html#concurrent.futures.Future) для доступа к результату.424425Эта функция предназначена для вызова из другого потока, отличного от того, в котором работает цикл событий. Использование:426427```python428# Создать корутину429coro = asyncio.sleep(1, result=3)430# Отправить корутину в заданный цикл431future = asyncio.run_coroutine_threadsafe(coro, loop)432# Ожидать результат с необязательным аргументом таймаута433assert future.result(timeout) == 3434```435436Если в корутине возникнет исключение, возвращённый future будет уведомлён. Его также можно использовать для отмены задачи в цикле событий:437438```python439try:440 result = future.result(timeout)441except asyncio.TimeoutError:442 print('The coroutine took too long, cancelling the task...')443 future.cancel()444except Exception as exc:445 print('The coroutine raised an exception: {!r}'.format(exc))446else:447 print('The coroutine returned: {!r}'.format(result))448```449450См. раздел [*concurrency and multithreading*](https://python-all.ru/3.4/library/asyncio-dev.html#asyncio-multithreading) документации.451452> **Примечание**453>454> В отличие от функций выше, [`run_coroutine_threadsafe()`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.run_coroutine_threadsafe) требует, чтобы аргумент *loop* был передан явно.455456Новое в версии 3.4.4,: 3.5.1457458#### `coroutine asyncio.sleep(delay, result=None, *, loop=None)`459460Создаёт [*корутину*](https://python-all.ru/3.4/library/asyncio-task.html#coroutine), которая завершается через указанное время (в секундах). Если указан *result*, то при завершении корутины он передаётся вызывающему коду.461462Точность задержки зависит от [*гранулярности цикла событий*](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio-delayed-calls).463464Эта функция – [*корутина*](https://python-all.ru/3.4/library/asyncio-task.html#coroutine).465466#### `asyncio.shield(arg, *, loop=None)`467468Ожидает future, защищая его от отмены.469470Выражение:471472```python473res = yield from shield(something())474```475476полностью эквивалентна следующему выражению:477478```python479res = yield from something()480```481482*Исключение составляет то,* что если корутина, содержащая его, отменена, задача, выполняющаяся в `something()`, не отменяется. С точки зрения `something()`, отмена не произошла. Но её вызывающий код всё равно отменён, поэтому выражение yield-from всё равно вызывает `CancelledError`. Примечание: если `something()` отменяется другими средствами, это всё равно отменит `shield()`.483484Если нужно полностью игнорировать отмену (не рекомендуется), можно объединить `shield()` с конструкцией try/except, как показано ниже:485486```python487try:488 res = yield from shield(something())489except CancelledError:490 res = None491```492493#### `asyncio.timeout(timeout, *, loop=None)`494495Возвращает менеджер контекста, который отменяет выполнение блока по истечении *timeout*:496497```python498with timeout(1.5):499 yield from inner()500```5015021. Если `inner()` выполняется быстрее, чем за `1.5` секунд, ничего не происходит.5032. В противном случае `inner()` отменяется внутри, но [`asyncio.TimeoutError`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.TimeoutError) возбуждается за пределами области действия менеджера контекста.504505#### `coroutine asyncio.wait(futures, *, loop=None, timeout=None, return_when=ALL_COMPLETED)`506507Ожидает завершения объектов Future и корутин, заданных последовательностью *futures* для завершения. Корутины будут обёрнуты в задачи. Возвращает два набора [`Future`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.Future): (done, pending).508509Последовательность *futures* не должна быть пустой.510511*timeout* можно использовать для задания максимального времени ожидания в секундах перед возвратом. *timeout* может быть целым числом (int) или числом с плавающей точкой (float). Если *timeout* не указан или равен `None`, время ожидания не ограничено.512513*return\_when* указывает, когда функция должна вернуть результат. Он должен быть одной из следующих констант модуля [`concurrent.futures`](https://python-all.ru/3.4/library/concurrent.futures.html#module-concurrent.futures):514515| Константа | Описание |516| --- | --- |517| `FIRST_COMPLETED` | Функция вернёт результат, когда любой future завершится или будет отменён. |518| `FIRST_EXCEPTION` | Функция вернёт результат, когда любой future завершится возбуждением исключения. Если ни один future не возбудит исключение, это эквивалентно `ALL_COMPLETED`. |519| `ALL_COMPLETED` | Функция вернёт результат, когда все future завершатся или будут отменены. |520521Эта функция – [*корутина*](https://python-all.ru/3.4/library/asyncio-task.html#coroutine).522523Использование:524525```python526done, pending = yield from asyncio.wait(fs)527```528529> **Примечание**530>531> Это не возбуждает [`asyncio.TimeoutError`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.TimeoutError)! Future, которые не завершились по истечении времени ожидания, возвращаются во втором наборе.532533#### `coroutine asyncio.wait_for(fut, timeout, *, loop=None)`534535Ожидает завершения одного [`Future`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.Future) или [*объекта корутины*](https://python-all.ru/3.4/library/asyncio-task.html#coroutine) с тайм-аутом. Если *timeout* равен `None`, ожидает до завершения future.536537Корутина будет обёрнута в [`Задача`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.Task).538539Возвращает результат Future или корутины. При возникновении тайм-аута задача отменяется и возбуждается [`asyncio.TimeoutError`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.TimeoutError). Чтобы избежать отмены задачи, оберните её в [`shield()`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.shield).540541Если ожидание отменяется, future *fut* также отменяется.542543Эта функция является [*корутиной*](https://python-all.ru/3.4/library/asyncio-task.html#coroutine), пример использования:544545```python546result = yield from asyncio.wait_for(fut, 60.0)547```548549Изменено в версии 3.4.3: Если ожидание отменяется, future *fut* теперь также отменяется.550