假设我的Python应用程序中有一个定义某种上下文的函数- user_id例如。此函数调用不将此上下文作为函数参数的其他函数。例如:
def f1(user, operation):
user_id = user.id
# somehow define user_id as a global/context variable for any function call inside this scope
f2(operation)
def f2(operation):
# do something, not important, and then call another function
f3(operation)
def f3(operation):
# get user_id if there is a variable user_id in the context, get `None` otherwise
user_id = getcontext("user_id")
# do something with user_id and operation
Run Code Online (Sandbox Code Playgroud)
我的问题是:
编辑
由于多种原因(架构遗留,库等),我无法/不会更改诸如的中间函数的签名f2,因此我不能仅 …
我正在尝试使用新的 contextvars 库(https://docs.python.org/3/library/contextvars.html)来使某些值在异步上下文中跨模块可用,类似于跨模块的 ContextVars,并且想知道是否有一种方法可以通过名称或标识符从给定的执行上下文中获取上下文变量,而无需直接导入上下文变量。
理想情况下,我想做类似以下的事情:
from _contextvars import ContextVar
language = ContextVar('language')
language.set('en-US')
Run Code Online (Sandbox Code Playgroud)
在一个单独的模块中,该模块可以服务网络请求或根据设置的语言获取翻译:
from _contextvars import copy_context
ctx = copy_context()
if 'language' in ctx:
lang_context_var = ctx.get('language') # get the context variable
lang_value = lang_context_var.get() # get the value
Run Code Online (Sandbox Code Playgroud)
我意识到 contextvars 库的 API 在 ContextVar 对象和值之间有一个映射,而不是字符串到值之间的映射,因此无法完成此查找,但我发现需要做的有点from module_with_context_var import language混乱并且容易分散在代码库中而不是当前上下文的单个包装器,这看起来像 copy_context() 应该是的。
任何能够在中央位置构造上下文变量获取和设置的好方法的指针也适用于协同例程/异步编程,我们将不胜感激!
根据标题,我想知道 Django 在通过 WSGI 或 Gunicorn 运行时是否使用一个线程来处理多个请求?
我知道从不打算访问的地方访问请求是一种不好的做法,但我仍然想这样做。(我认为有充分的理由,例如在我的自定义模板加载器中访问当前用户和站点。Django 模板加载器不提供这两个实体。)
现在我设法使用以下代码从任何地方访问用户等:
import threading
_thread_locals = threading.local()
def get_current_request():
return getattr(_thread_locals, "request", None)
class RequestThreadMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
_thread_locals.request = request
response = self.get_response(request)
return response
Run Code Online (Sandbox Code Playgroud)
我的问题/担忧是:是否保证请求/用户不会在生产中混淆?例如,我担心第二个用户被识别为第一个用户,因为该线程用于我的多个请求。或者,该请求在原始请求尚未完成时被另一个请求覆盖。这是可能的,还是每个请求在 WSGI 和 Gunicorn 中都有自己的本地线程?