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

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

Корутины

Coroutines, объявленные с синтаксисом async/await, являются предпочтительным способом написания приложений asyncio. Например, следующий фрагмент кода печатает «hello», ждет 1 секунду, а затем печатает «world»:

>>> import asyncio

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

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

Обратите внимание, что простой вызов coroutine не приведет к планированию ее выполнения:

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

Чтобы фактически запустить coroutine, asyncio предоставляет три основных механизма:

  • Функция asyncio.run() для запуска функции верхнего уровня «main()» (см. пример выше).

  • Ожидание в корутине. Следующий фрагмент кода выведет «hello» после ожидания в течение 1 секунды, а затем выведет «world» после ожидания в течение еще 2 секунд:

    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())
    

    Ожидаемый результат:

    started at 17:13:52
    hello
    world
    finished at 17:13:55
    
  • Функция asyncio.create_task() для одновременного запуска coroutines как asyncio Tasks.

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

    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')}")
    
        # Wait until both tasks are completed (should take
        # around 2 seconds.)
        await task1
        await task2
    
        print(f"finished at {time.strftime('%X')}")
    

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

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

Ожидания

Мы говорим, что объект является awaitable, если он может быть использован в выражении await. Многие API asyncio разработаны так, чтобы принимать awaitables.

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

Корутины

Корутины Python являются awaitables и поэтому могут быть ожидаемы от других корутин:

import asyncio

async def nested():
    return 42

async def main():
    # Nothing happens if we just call "nested()".
    # A coroutine object is created but not awaited,
    # so it *won't run at all*.
    nested()

    # Let's do it differently now and await it:
    print(await nested())  # will print "42".

asyncio.run(main())

Важно

В данной документации термин «coroutine» может использоваться для двух тесно связанных понятий:

  • кораутинная функция: функция async def;

  • объект корутинной функции: объект, возвращаемый при вызове корутинной функции.

asyncio также поддерживает унаследованные generator-based coroutines.

Задачи

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

Когда coroutine обернута в Task с функциями типа asyncio.create_task(), coroutine автоматически планируется к выполнению в ближайшее время:

import asyncio

async def nested():
    return 42

async def main():
    # Schedule nested() to run soon concurrently
    # with "main()".
    task = asyncio.create_task(nested())

    # "task" can now be used to cancel "nested()", or
    # can simply be awaited to wait until it is complete:
    await task

asyncio.run(main())

Фьючерсы

Future - это специальный низкоуровневый ожидаемый объект, который представляет собой эвентуальный результат асинхронной операции.

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

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

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

Будущие объекты, иногда открываемые библиотеками и некоторыми API asyncio, можно ожидать:

async def main():
    await function_that_returns_a_future_object()

    # this is also valid:
    await asyncio.gather(
        function_that_returns_a_future_object(),
        some_python_coroutine()
    )

Хорошим примером низкоуровневой функции, возвращающей объект Future, является loop.run_in_executor().

Запуск программы asyncio

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

Выполните coroutine coro и верните результат.

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

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

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

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

Пример:

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

asyncio.run(main())

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

Изменено в версии 3.9: Обновлено для использования loop.shutdown_default_executor().

Примечание

Исходный код для asyncio.run() можно найти в Lib/asyncio/runners.py.

Создание задач

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

Заверните coro coroutine в Task и запланируйте его выполнение. Верните объект Task.

Если name не является None, оно устанавливается как имя задачи с помощью Task.set_name().

Задание выполняется в цикле, возвращенном командой get_running_loop(), RuntimeError поднимается, если в текущем потоке нет запущенного цикла.

Важно

Сохраните ссылку на результат этой функции, чтобы избежать исчезновения задачи в середине выполнения. В цикле событий сохраняются только слабые ссылки на задачи. Задача, на которую нет ссылки в другом месте, может быть собрана в мусор в любой момент, даже до того, как она будет выполнена. Для надежного выполнения фоновых задач по принципу «запустил и забыл», соберите их в коллекцию:

background_tasks = set()

for i in range(10):
    task = asyncio.create_task(some_coro(param=i))

    # Add task to the set. This creates a strong reference.
    background_tasks.add(task)

    # To prevent keeping references to finished tasks forever,
    # make each task remove its own reference from the set after
    # completion:
    task.add_done_callback(background_tasks.discard)

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

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

Спать

coroutine asyncio.sleep(delay, result=None)

Блокировать на задержку секунд.

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

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

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

Deprecated since version 3.8, removed in version 3.10: Параметр loop. Начиная с версии 3.7 эта функция неявно получает текущий запущенный цикл. Для получения дополнительной информации см. раздел What’s New in 3.10’s Removed section.

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

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())

Изменено в версии 3.10: Удален параметр loop.

Одновременное выполнение задач

awaitable asyncio.gather(*aws, return_exceptions=False)

Выполните awaitable objects в последовательности aws последовательно.

Если какой-либо awaitable в aws является coroutine, он автоматически планируется как Task.

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

Если return_exceptions равно False (по умолчанию), то первое возникшее исключение немедленно передается задаче, ожидающей на gather(). Другие ожидающие задачи в последовательности aws не будут отменены и продолжат выполнение.

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

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

Если какая-либо Задача или Будущее из последовательности aws отменяется, она рассматривается как если бы она вызвала CancelledError – вызов gather() в этом случае не отменяется. Это делается для того, чтобы отмена одной представленной Задачи/Будущего не привела к отмене других Задач/Будущего.

Изменено в версии 3.10: Удален параметр loop.

Пример:

import asyncio

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

async def main():
    # Schedule three calls *concurrently*:
    L = await asyncio.gather(
        factorial("A", 2),
        factorial("B", 3),
        factorial("C", 4),
    )
    print(L)

asyncio.run(main())

# Expected output:
#
#     Task A: Compute factorial(2), currently i=2...
#     Task B: Compute factorial(3), currently i=2...
#     Task C: Compute factorial(4), currently i=2...
#     Task A: factorial(2) = 2
#     Task B: Compute factorial(3), currently i=3...
#     Task C: Compute factorial(4), currently i=3...
#     Task B: factorial(3) = 6
#     Task C: Compute factorial(4), currently i=4...
#     Task C: factorial(4) = 24
#     [2, 6, 24]

Примечание

Если return_exceptions равно False, отмена функции gather() после того, как она была помечена как выполненная, не отменит ни одного из переданных ожиданий. Например, gather может быть помечена как выполненная после распространения исключения на вызывающую сторону, поэтому вызов gather.cancel() после перехвата исключения (поднятого одним из ожиданий) из gather не приведет к отмене других ожиданий.

Изменено в версии 3.7: Если отменяется сам gather, отмена распространяется независимо от return_exceptions.

Изменено в версии 3.10: Удален параметр loop.

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

Защита от отмены

awaitable asyncio.shield(aw)

Защитить awaitable object от превращения в cancelled.

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

Заявление:

res = await shield(something())

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

res = await something()

за исключением того, что если содержащая его coroutine отменяется, то Task, выполняющийся в something(), не отменяется. С точки зрения something(), отмена не произошла. Хотя ее вызывающая часть все равно отменяется, поэтому выражение «await» все равно вызывает ошибку CancelledError.

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

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

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

Изменено в версии 3.10: Удален параметр loop.

Не рекомендуется, начиная с версии 3.10: Предупреждение об устаревании выдается, если aw не является Future-like объектом и нет запущенного цикла событий.

Тайм-ауты

coroutine asyncio.wait_for(aw, timeout)

Дождитесь завершения aw awaitable с таймаутом.

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

timeout может быть либо None, либо float или int - число секунд для ожидания. Если timeout равен None, блокируйте до тех пор, пока будущее не завершится.

Если происходит тайм-аут, он отменяет задание и поднимает asyncio.TimeoutError.

Чтобы избежать задачи cancellation, оберните ее в shield().

Функция будет ждать, пока будущее не будет фактически отменено, поэтому общее время ожидания может превысить timeout. Если во время отмены произойдет исключение, оно будет передано.

Если ожидание отменяется, то будущее aw также отменяется.

Изменено в версии 3.10: Удален параметр loop.

Пример:

async def eternity():
    # Sleep for one hour
    await asyncio.sleep(3600)
    print('yay!')

async def main():
    # Wait for at most 1 second
    try:
        await asyncio.wait_for(eternity(), timeout=1.0)
    except asyncio.TimeoutError:
        print('timeout!')

asyncio.run(main())

# Expected output:
#
#     timeout!

Изменено в версии 3.7: Когда aw отменяется из-за таймаута, wait_for ожидает отмены aw. Ранее он немедленно вызывал asyncio.TimeoutError.

Изменено в версии 3.10: Удален параметр loop.

Примитивы ожидания

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

Выполнять awaitable objects в итерабле aws параллельно и блокировать до выполнения условия, заданного return_when.

Итерабельность aws не должна быть пустой.

Возвращает два набора Задач/Функций: (done, pending).

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

done, pending = await asyncio.wait(aws)

timeout (число float или int), если указано, может использоваться для управления максимальным количеством секунд ожидания перед возвратом.

Обратите внимание, что эта функция не поднимает asyncio.TimeoutError. Фьючерсы или задачи, которые не были выполнены в момент тайм-аута, просто возвращаются во втором наборе.

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

Постоянная

Описание

FIRST_COMPLETED

Функция возвращается, когда любое будущее завершается или отменяется.

FIRST_EXCEPTION

Функция вернется, когда любое будущее завершится, вызвав исключение. Если ни одно будущее не вызывает исключения, то это эквивалентно ALL_COMPLETED.

ALL_COMPLETED

Функция вернется, когда все фьючерсы завершатся или будут отменены.

В отличие от wait_for(), wait() не отменяет фьючерсы при возникновении тайм-аута.

Не рекомендуется, начиная с версии 3.8: Если какой-либо awaitable в aws является coroutine, он автоматически планируется как Task. Передача объектов coroutines в wait() напрямую неактуальна, так как приводит к confusing behavior.

Изменено в версии 3.10: Удален параметр loop.

Примечание

wait() автоматически планирует короутины как Задачи и позже возвращает эти неявно созданные объекты Задач в наборах (done, pending). Поэтому следующий код не будет работать так, как ожидалось:

async def foo():
    return 42

coro = foo()
done, pending = await asyncio.wait({coro})

if coro in done:
    # This branch will never be run!

Вот как можно исправить приведенный выше фрагмент:

async def foo():
    return 42

task = asyncio.create_task(foo())
done, pending = await asyncio.wait({task})

if task in done:
    # Everything will work as expected now.

Deprecated since version 3.8, will be removed in version 3.11: Передача объектов coroutine непосредственно в wait() устарела.

Изменено в версии 3.10: Удален параметр loop.

asyncio.as_completed(aws, *, timeout=None)

Выполнять awaitable objects в итерабле aws одновременно. Возвращает итератор короутинов. Каждая возвращенная корутина может быть ожидаема для получения самого раннего следующего результата из итератора оставшихся ожидаемых.

Повышает asyncio.TimeoutError, если таймаут произойдет до того, как все фьючерсы будут выполнены.

Изменено в версии 3.10: Удален параметр loop.

Пример:

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

Изменено в версии 3.10: Удален параметр loop.

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

Бег по нитям

coroutine asyncio.to_thread(func, /, *args, **kwargs)

Асинхронное выполнение функции func в отдельном потоке.

Любые *args и **kwargs, переданные для этой функции, напрямую передаются в func. Также передается текущее значение contextvars.Context, что позволяет обращаться к контекстным переменным из потока цикла событий в отдельном потоке.

Возвращает корутину, которую можно ожидать, чтобы получить конечный результат func.

Эта функция coroutine в первую очередь предназначена для выполнения функций/методов, связанных с IO, которые в противном случае блокировали бы цикл событий, если бы выполнялись в главном потоке. Например:

def blocking_io():
    print(f"start blocking_io at {time.strftime('%X')}")
    # Note that time.sleep() can be replaced with any blocking
    # IO-bound operation, such as file operations.
    time.sleep(1)
    print(f"blocking_io complete at {time.strftime('%X')}")

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

    await asyncio.gather(
        asyncio.to_thread(blocking_io),
        asyncio.sleep(1))

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


asyncio.run(main())

# Expected output:
#
# started main at 19:50:53
# start blocking_io at 19:50:53
# blocking_io complete at 19:50:54
# finished main at 19:50:54

Прямой вызов blocking_io() в любой короутине заблокирует цикл событий на все его время, что приведет к дополнительной 1 секунде времени выполнения. Вместо этого, используя asyncio.to_thread(), мы можем запустить его в отдельном потоке без блокировки цикла событий.

Примечание

Из-за GIL, asyncio.to_thread() обычно можно использовать только для того, чтобы сделать IO-связанные функции неблокирующими. Однако, для модулей расширения, выпускающих GIL, или альтернативных реализаций Python, не имеющих его, asyncio.to_thread() может также использоваться для функций, связанных с процессором.

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

Планирование из других потоков

asyncio.run_coroutine_threadsafe(coro, loop)

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

Возвращает concurrent.futures.Future для ожидания результата от другого потока ОС.

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

# Create a coroutine
coro = asyncio.sleep(1, result=3)

# Submit the coroutine to a given loop
future = asyncio.run_coroutine_threadsafe(coro, loop)

# Wait for the result with an optional timeout argument
assert future.result(timeout) == 3

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

try:
    result = future.result(timeout)
except concurrent.futures.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 в документации.

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

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

Интроспекция

asyncio.current_task(loop=None)

Возвращает текущий запущенный экземпляр Task или None, если ни одна задача не запущена.

Если loop равен None, то get_running_loop() используется для получения текущего цикла.

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

asyncio.all_tasks(loop=None)

Возвращает набор еще не завершенных Task объектов, выполняемых циклом.

Если loop равен None, то для получения текущего цикла используется get_running_loop().

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

Объект задачи

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

Объект Future-like, который запускает Python coroutine. Не является потокобезопасным.

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

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

Для создания Задач используйте функцию высокого уровня asyncio.create_task() или функции низкого уровня loop.create_task() или ensure_future(). Не рекомендуется создавать Задачи вручную.

Для отмены запущенной задачи используйте метод cancel(). Его вызов приведет к тому, что Task выбросит исключение CancelledError в обернутую coroutine. Если во время отмены корутина ожидает объект Future, объект Future будет отменен.

cancelled() может быть использован для проверки того, была ли отменена задача. Метод возвращает True, если обернутая короутина не подавила исключение CancelledError и действительно была отменена.

asyncio.Task наследует от Future все свои API, кроме Future.set_result() и Future.set_exception().

Задачи поддерживают модуль contextvars. Когда создается задача, она копирует текущий контекст, а затем запускает свою программу в скопированном контексте.

Изменено в версии 3.7: Добавлена поддержка модуля contextvars.

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

Не рекомендуется, начиная с версии 3.10: Предупреждение об устаревании выдается, если не указан loop и нет запущенного цикла событий.

cancel(msg=None)

Запрос на отмену задания.

Это позволяет организовать исключение CancelledError, которое будет брошено в обернутую coroutine на следующем цикле цикла событий.

Затем корутина имеет возможность очистить или даже отклонить запрос, подавив исключение с помощью команды try … … …. except CancelledErrorfinally блоком. Поэтому, в отличие от Future.cancel(), Task.cancel() не гарантирует, что задача будет отменена, хотя полное подавление отмены не является обычным явлением и активно не рекомендуется.

Изменено в версии 3.9: Добавлен параметр msg.

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

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

    try:
        # Wait for 1 hour
        await asyncio.sleep(3600)
    except asyncio.CancelledError:
        print('cancel_me(): cancel sleep')
        raise
    finally:
        print('cancel_me(): after sleep')

async def main():
    # Create a "cancel_me" Task
    task = asyncio.create_task(cancel_me())

    # Wait for 1 second
    await asyncio.sleep(1)

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

asyncio.run(main())

# Expected output:
#
#     cancel_me(): before sleep
#     cancel_me(): cancel sleep
#     cancel_me(): after sleep
#     main(): cancel_me is cancelled now
cancelled()

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

Задача отменена, если отмена была запрошена с помощью cancel() и обернутая coroutine распространила брошенное в нее исключение CancelledError.

done()

Возвращает True, если задача выполнена.

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

result()

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

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

Если задача была отменена, этот метод вызывает исключение CancelledError.

Если результат задачи еще не доступен, этот метод вызывает исключение InvalidStateError.

exception()

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

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

Если задача была отменена, этот метод вызывает исключение CancelledError.

Если задача еще не закончена, этот метод вызывает исключение InvalidStateError.

add_done_callback(callback, *, context=None)

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

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

Более подробную информацию см. в документации по Future.add_done_callback().

remove_done_callback(callback)

Удалить callback из списка обратных вызовов.

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

Более подробную информацию см. в документации по Future.remove_done_callback().

get_stack(*, limit=None)

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

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

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

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

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

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

Выведите стек или обратную трассировку для этой задачи.

Это дает вывод, аналогичный выводу модуля traceback для кадров, полученных с помощью get_stack().

Аргумент limit передается в get_stack() напрямую.

Аргумент file - это поток ввода/вывода, в который записывается вывод; по умолчанию вывод записывается в sys.stderr.

get_coro()

Возвращает объект coroutine, обернутый Task.

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

get_name()

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

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

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

set_name(value)

Задайте имя задачи.

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

В реализации Task по умолчанию имя будет видно в выводе repr() объекта задачи.

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

Корутины на основе генераторов

Примечание

Поддержка coroutines на основе генераторов является устаревшей и будет удалена в Python 3.11.

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

Корутины на основе генераторов должны быть украшены @asyncio.coroutine, хотя это не является обязательным условием.

@asyncio.coroutine

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

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

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

async def main():
    await old_style_coroutine()

Этот декоратор не следует использовать для :keyword:`async def`корутинов.

Deprecated since version 3.8, will be removed in version 3.11: Вместо этого используйте async def.

asyncio.iscoroutine(obj)

Возвращает True, если obj является coroutine object.

Этот метод отличается от inspect.iscoroutine() тем, что он возвращает True для coroutines на основе генератора.

asyncio.iscoroutinefunction(func)

Возвращает True, если func является coroutine function.

Этот метод отличается от inspect.iscoroutinefunction() тем, что он возвращает True для генераторных функций coroutine, украшенных @coroutine.

Вернуться на верх