Python 3.7+contextvarsterm
contextvars.ContextVar
context variables
A context variable: each asyncio task and each thread sees its own value; the replacement for threading.local in async code.
Syntax
var = contextvars.ContextVar(name, *, default=...)
In asyncio all tasks run on one thread, so a threading.local is shared and values overwrite each other; a ContextVar is copied into each task by create_task() and does not leak between them. Create it once at module level, not inside a function. get() with no value and no default raises LookupError. The default is shared by every context: a mutable list there is common to all.
Examples
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('значения нет') # → значения нет
See also
Open in the full glossarydocs.python.orgReport an inaccuracy