Spec-Zone.ru › Python 3.10

Потоки и задачи

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

  • Потоки
  • Объекты-awaitables
  • Запуск программы asyncio
  • Создание задач
  • Ожидание
  • Выполнение задач параллельно
  • Защита от отмены
  • Таймауты
  • Примитивы ожидания
  • Выполнение в потоках
  • Планирование из других потоков
  • Интроспекция
  • Объект задачи
  • Потоки, основанные на генераторах

Потоки

Исходный код: Lib/asyncio/coroutines.py

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

>>> import asyncio

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

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

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

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

Для фактического запуска потока 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() для одновременного запуска потоков как 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
    

Объекты-awaitables

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

Существует три основных типа объектов-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())

Важно

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

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

asyncio также поддерживает устаревшие потоки, основанные на генераторах generator-based.

Задачи

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

Когда поток заворачивается в задачу с помощью функций, таких как asyncio.create_task(), поток автоматически планируется для скорого запуска:

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 — это специальный низкоуровневый объект-awaitable, представляющий конечный результат асинхронной операции.

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

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

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

Объекты 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)

Выполнить поток 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.

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

Исходный код: Lib/asyncio/tasks.py

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

Обернуть поток coro поток в 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)

Ожидать delay секунд.

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

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

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

Устарело начиная с версии 3.8, удалено в версии 3.10: Параметр loop. Эта функция неявно получает текущий работающий цикл с версии 3.7. См. Что нового в 3.10 (раздел Удаленное) для получения дополнительной информации.

Пример потока, отображающего текущую дату каждую секунду в течение 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)

Запустить объекты-awaitables в последовательности aws одновременно.

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

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

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

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

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

Если какая-либо задача (Task) или будущее (Future) из последовательности 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() после того, как она была помечена как завершённая, не отменит отправленные awaitables. Например, gather может быть помечена как завершённая после передачи исключения вызывающей стороне, поэтому вызов gather.cancel() после перехвата исключения (поднятого одним из awaitables) от gather не отменит другие awaitables.

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

Изменено в версии 3.10: Параметр loop удалён.

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

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

awaitable asyncio.shield(aw)

Защитить объект-awaitable от cancelled.

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

Выражение:

task = asyncio.create_task(something())
res = await shield(task)

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

res = await something()

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

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

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

task = asyncio.create_task(something())
try:
    res = await shield(task)
except CancelledError:
    res = None

Важно

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

Изменено в версии 3.10: Параметр loop удалён.

Устарело начиная с версии 3.10: Выдаётся предупреждение об устаревании, если aw не является объектом типа Future, и нет работающей событийной петли.

Таймауты

coroutine asyncio.wait_for(aw, timeout)

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

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

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)

Запустить объекты-awaitables в итерируемом объекте aws одновременно и заблокироваться до тех пор, пока не будет выполнено условие, указанное в return_when.

Итерируемый объект aws не должен быть пустым.

Возвращает два множества задач/будущих: (done, pending).

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

done, pending = await asyncio.wait(aws)

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

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

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

Константа

Описание

FIRST_COMPLETED

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

FIRST_EXCEPTION

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

ALL_COMPLETED

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

В отличие от wait_for(), wait() не отменяет будущие при истечении таймаута.

Устарело начиная с версии 3.8: Если любой awaitable в aws является корутиной, она автоматически планируется как задача (Task). Передача объектов корутин в wait() напрямую устарела, так как это приводит к неясному поведению.

Изменено в версии 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.

Устарело начиная с версии 3.8, будет удалено в версии 3.11: Передача объектов корутин в wait() напрямую устарела.

Изменено в версии 3.10: Параметр loop удалён.

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

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

Поднимает asyncio.TimeoutError, если таймаут истекает до завершения всех будущих.

Пример:

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

Изменено в версии 3.10: Параметр loop удалён.

Устарело начиная с версии 3.10: Выдаётся предупреждение об устаревании, если не все объекты awaitable в итерируемом объекте aws являются объектами типа Future, и нет работающей событийной петли.

END_OF_DOCUMENT_MARKER

Выполнение в потоках

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

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

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

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

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

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() обычно можно использовать только для того, чтобы сделать функции, связанные с вводом-выводом, неблокирующими. Однако для модулей расширения, которые освобождают 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}')

См. раздел конкурентности и многопоточности документации.

В отличие от других функций 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.

END_OF_DOCUMENT_MARKER

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

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

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

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

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

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

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

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

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

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

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

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

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

cancel(msg=None)

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

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

Затем у корутины есть возможность очистить или даже отклонить запрос, подавив исключение с помощью блока try … … except CancelledError … finally. Поэтому, в отличие от 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(), и обернутая корутина распространила исключение CancelledError, сброшенное в неё.

done()

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

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

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)

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

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

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

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

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

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

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

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

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

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

get_coro()

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

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

get_name()

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

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

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

set_name(value)

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

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

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

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

Генераторные корутины

Примечание

Поддержка генераторных корутин устарела и удалена в Python 3.11.

Генераторные корутины появились до синтаксиса async/await. Это генераторы Python, которые используют yield from выражения для ожидания выполнения задач и других корутин.

Генераторные корутины должны быть декорированы с помощью @asyncio.coroutine, хотя это не обязательно.

@asyncio.coroutine

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

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

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

async def main():
    await old_style_coroutine()

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

Устарело начиная с версии 3.8, будет удалено в версии 3.11: Используйте async def вместо этого.

asyncio.iscoroutine(obj)

Возвращает True, если obj является объектом корутины.

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

asyncio.iscoroutinefunction(func)

Возвращает True, если func является функцией-корутиной.

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

© 2001–2023 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.10/library/asyncio-task.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API