【问题标题】:Access to contextvars in asyncio add_done_callback callback在 asyncio add_done_callback 回调中访问上下文变量
【发布时间】:2021-07-02 15:33:03
【问题描述】:

在 Python 异步函数中,我正在创建 ContextVar、任务并为其附加回调:

bbb = contextvars.ContextVar('aaa')
bbb.set(3)
task = self.loop.create_task(self.someFunc())
task.add_done_callback(self.commonCallback)
bbb.set(4)

在回调中我首先启动调试器:

def commonCallback(self, result):
 pdb.set_trace()
 try:
  r = result.result()
  print(r)
 except:
  self.log.exception('commonCallback')

在调试器中:

-> try:
(Pdb) bbb.get()
*** NameError: name 'bbb' is not defined
(Pdb) ctx = contextvars.copy_context()
(Pdb) print(list(ctx.items()))
[(<ContextVar name='aaa' at 0xa8245df0>, 3)]
(Pdb) 

ContextVar 在那里,但我无法访问它。所以,我错过了一些东西,但找不到什么?

【问题讨论】:

  • 您为什么期望在一个函数中定义的bbb 局部变量可以在代码中其他地方定义的commonCallback 函数中访问? documentation 声明“应在顶层模块级别创建上下文变量”。
  • @user4815162342 谢谢,就是这样。我知道这是微不足道的,而且像往常一样。我只是看不到它。可悲的是,我没有足够的声誉来支持评论。
  • 没问题,我现在发布了一个类似的建议作为您可以接受的答案。

标签: python python-asyncio asynccallback python-contextvars


【解决方案1】:

您无需导入顶级模块即可从上下文中获取值。 contextvars.Context 有 __iter__ 方法。您可以使用 for 循环来获取值:

def get_ctx_var_value(ctx, var_name, default_value=None):
    for var in ctx:
        if var.name == var_name:
            return ctx[var]
    return default_value

ctx = contextvars.copy_context()
var_value = get_ctx_var_value(ctx, 'aaa')

【讨论】:

    【解决方案2】:

    bbb 局部变量是在一个地方定义的,因此它不会在另一个地方自动访问,例如代码中其他地方定义的commonCallback 函数。 documentation 声明“应在顶层模块级别创建上下文变量”,因此您应该先尝试。

    【讨论】:

      猜你喜欢
      • 2019-04-09
      • 2017-11-04
      • 2016-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多