假设我的 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
我的问题是:
- Python 3.7 的 上下文变量 可以用于此吗?如何?
- 这是这些上下文变量的目的吗?
- 如何使用 Python v3.6 或更早版本执行此操作?
编辑
由于多种原因 (体系结构遗留问题、库等), 我不能/不会更改中间函数的签名,例如 f2
,所以我不能只传递 user_id
作为参数,既不将所有这些函数放在同一个类中。
原文由 Jundiaius 发布,翻译遵循 CC BY-SA 4.0 许可协议
您可以在 Python 3.7 中使用
contextvars
来满足您的要求。这通常非常简单:The
set
method on theContextVar
returns aToken
instance, which you can use to reset the variable to the value it had before theset
手术发生了。因此,如果您想要f1
以原来的方式恢复事物(对于user_id
上下文变量不是很有用,但与在decimal
中设置精度更相关---
模块),你可以这样做:contextvars
模块的内容远不止于此,但您几乎可以肯定不需要处理其他内容。如果您从头开始编写自己的异步框架,您可能只需要创建自己的上下文并在其他上下文中运行代码。如果您只是 使用 现有的框架(或编写一个您希望与异步代码一起玩的库),则不需要处理这些东西。只需创建一个全局
ContextVar
(或查找您的框架已经定义的一个)和get
和set
值应该如上所示去。很多
contextvars
使用可能会在后台进行,作为各种库的实现细节,这些库希望具有“全局”状态,不会泄漏线程之间或内部独立异步任务之间的更改一个线程。上面的例子在这种情况下可能更有意义:f1
和f3
是同一个库的一部分,f2
是用户传递的回调进入其他地方的图书馆。