Python Glossary English

Python 3.7+contextvarsпонятие

contextvars.ContextVar

контекстные переменные

Контекстная переменная: значение своё у каждой задачи asyncio и каждого потока; замена threading.local в async-коде.

Синтаксис

var = contextvars.ContextVar(name, *, default=...)

В asyncio все задачи крутятся в одном потоке, поэтому threading.local у них общий и значения перетираются; ContextVar копируется в каждую задачу при create_task() и не протекает между ними. Создают её один раз на уровне модуля, а не в функции. get() без значения и без default бросает LookupError. default разделяется всеми контекстами: изменяемый список в нём — общий.

Примеры

import asyncio, contextvars, threading
local = threading.local()
request_id = contextvars.ContextVar('request_id')
async def handle(n):
    local.n = n
    request_id.set(n)
    await asyncio.sleep(0.01 * (3 - n))
    return local.n, request_id.get()
async def main():
    return await asyncio.gather(*(handle(i) for i in range(3)))
print(asyncio.run(main()))  # → [(2, 0), (2, 1), (2, 2)] — local перетёрт
import contextvars
user = contextvars.ContextVar('user')
print(user.get('гость'))  # → гость
try:
    user.get()
except LookupError:
    print('значения нет')  # → значения нет

См. также

Открыть в полном глоссарииdocs.python.orgСообщить о неточности