如何在 Python 3.5 中的异步方法调用之间传递上下文?

How to pass context between asynchronous method calls in Python 3.5?

如何在不使用方法参数的情况下将异步方法调用的上下文传递给另一个调用?

我需要使用一种流 ID 来丰富日志消息的功能,以便我可以轻松地跟踪特定调用方法流的所有日志消息。

我使用 Python 的 async 和 await 关键字 (Python 3.5.x).

你应该使用 Context Variables introduced in Python 3.7, and I have a polyfill for Python < 3.7 as aiocontextvars.

上一个回答:

You may want to take a look at tasklocals and aiolocals.

我通过设置自定义 task factory 解决了这个问题。事实证明,每个任务都有一个上下文(与每个异步调用的上下文相比)对我来说就足够了。

我正在研究 aiotask-context package。这是在任务之间传递上下文的一种非常简单的方法(使用 awaityield from 调用)。如果你不想使用这个包,你仍然可以使用这个想法:)。

我也在研究如何为 ensure_future 调用传播它。

import contextvars
c_id = contextvars.ContextVar("context_id", default=None)

def get_context_id():
    return c_id.get()

def set_context_id(value):
    c_id.set(value)

为了做到这一点,我付出了很多努力。如果有人仍在寻找答案,那么他们可以在这里参考。这适用于 Python3.7 以上。

  • 创建 contextvars.ContextVar 的实例。
  • 您可以在此处为该变量指定上下文变量名称和默认值,以防在当前上下文中找不到该变量时使用默认值。
  • 使用 setter 设置值,您可以在同一上下文中使用 getter 获得相同的值。
  • 在顶层定义一次 ContextVar,而不是在闭包内部(即函数或 class 等),因为上下文的垃圾收集是不合适的。