在扭曲中使用上下文

Using context in twisted

我尝试使用 twisted.python.context,但在第一个 deferToThread 之后上下文消失了。

from twisted.internet import reactor, defer, threads
from twisted.python import context

def _print_context(msg):
    cont = context.get('cont')
    print "{msg}: {context}".format(msg=msg, context=cont)

def sub_call():
    _print_context("In sub_call")

@defer.inlineCallbacks
def with_context():
    _print_context("before thread")
    yield threads.deferToThread(sub_call)
    _print_context("after thread")
    reactor.stop()

def test():
    cont = {'cont': "TestContext"}
    context.call(cont, with_context)
reactor.callLater(0, test)
reactor.run()

我在 deferToThread 之前和 sub_call 中有上下文,但在 deferToThread 之后没有上下文。

deferToThread之后有什么方法可以获取上下文吗?

context.call 为传递给它的对象的调用持续时间设置上下文 - 在本例中为 with_context.

with_context 是一个 inlineCallbacks 包装的生成器函数。第一次调用它会创建一个新的生成器并将其迭代到第一个 yield 语句。然后它的执行被挂起,就调用者而言,调用 returns。此时弹出上下文堆栈并丢弃您提供的上下文。

稍后,inlineCallbacks 的实现确保生成器将进一步迭代,以便执行 yield 语句之后的代码。但是,上下文已被丢弃。

没有简单的方法来解决这个问题。 twisted.python.context 没有尝试解决 异步 上下文管理的问题。此外,twisted.python.context 相当糟糕,实际上应该编写任何程序来使用它。

我建议退后一步,重新评估您的选择。通过创建 class 并在其实例上使用实例属性在方法调用之间携带状态,您可能会得到更好的服务。