使用扭曲的上下文

时间:2015-01-15 13:05:19

标签: python 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()

我在deferToThreadsub_call之前有上下文,但在deferToThread之后没有上下文。

有没有办法在deferToThread之后有上下文?

1 个答案:

答案 0 :(得分:4)

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

with_contextinlineCallbacks包裹的生成器函数。第一次调用它会创建一个新生成器,并将其迭代到第一个yield语句。然后暂停执行,并且就调用者而言,调用返回。此时,将弹出上下文堆栈,并放弃您提供的上下文。

稍后,inlineCallbacks的实现可确保生成器进一步迭代,以便yield语句执行后的代码。但是,背景已被抛弃。

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

我建议退一步,重新评估您的选择。通过创建一个类并在其实例上使用实例属性来在方法调用之间传递状态,可能会更好地服务。