Контекстные переменные — это механизм для хранения и передачи данных в рамках определенного контекста выполнения, особенно полезный в асинхронном коде. Они были введены в Python 3.7 как часть модуля contextvars
.
import contextvars
# Создаем контекстную переменную
user_id = contextvars.ContextVar('user_id', default=None)
# Устанавливаем значение в текущем контексте
token = user_id.set(123)
# Получаем значение
print(user_id.get()) # Выведет: 123
# Восстанавливаем предыдущее значение
user_id.reset(token)
Потокобезопасность (Thread Safety):
Асинхронная поддержка (Async Support):
import asyncio
import contextvars
request_id = contextvars.ContextVar('request_id')
async def process_request():
# У каждого вызова будет свое значение
request_id.set(id(request))
await some_async_operation()
print(f"Processing request {request_id.get()}")
async def some_async_operation():
# Все еще имеет доступ к правильному request_id
print(f"Operation for {request_id.get()}")
from fastapi import Request
import contextvars
current_request = contextvars.ContextVar('current_request')
async def middleware(request: Request):
token = current_request.set(request)
try:
return await call_next(request)
finally:
current_request.reset(token)
user_context = contextvars.ContextVar('user_context')
def auth_middleware(request):
user_data = authenticate(request)
token = user_context.set(user_data)
request.state.cleanup = lambda: user_context.reset(token)
Метод | Потоки | Async | Изоляция контекста |
---|---|---|---|
Global variables | ❌ | ❌ | ❌ |
Thread-local | ✅ | ❌ | ✅ |
contextvars | ✅ | ✅ | ✅ |
contextvars
— мощный инструмент для управления состоянием в асинхронных приложениях и микросервисных архитектурах, обеспечивающий изолированный контекст выполнения для каждого запроса или цепочки вызовов. Они особенно полезны в веб-фреймворках и распределенных системах для передачи метаданных между компонентами.