【问题标题】:Tornado context manager called in gen.coroutine在 gen.coroutine 中调用的 Tornado 上下文管理器
【发布时间】:2013-09-22 21:08:24
【问题描述】:

我现在正在使用 AMQP pika 库。我想要开发的是上下文管理器或装饰器,以确保与 Rabbit 建立连接。无法在装饰器中使用生成器的问题,因为它们必须返回被调用的函数。以下示例引发异常:

def ensure_conn(func):

    @gen.coroutine
    def wrapper(self, *args, **kwargs):
        yield self.connection.ensure_connection()
        return func(*args, **kwargs)

    return wrapper

上下文管理器也存在几乎相同的问题。两次使用yield是不可能的。以下示例引发生成器未停止的异常。

@contextlib.contextmanager
@gen.coroutine
def ensure_conn(self):
    yield self.ensure_connection()
    yield

请推荐另一种方法?当然,简单的协程调用我已经很满意了。谢谢。

【问题讨论】:

  • 第二个例子为什么要yield两次?
  • 谢谢@Michael0x2a。通过查看 contextlib.contextmanager 的源代码,我了解到它在 _enter_ 方法处调用生成器函数 (ensure_conn) 的 next。正如我们现在 .next() on gen 在withstatement 中传输执行上下文。在 _exit_ 方法中,它确保生成器已正常停止。但是在我的例子中 self.ensure_connection 是返回未来对象的龙卷风协程。通过产生它, gen.coroutine 装饰器从该点传输执行上下文并等待,而未来的对象将准备好返回一个值(答案)。
  • 为什么这被标记为“扭曲”?

标签: python twisted tornado coroutine


【解决方案1】:

实际上,有两种方法可以创建上下文管理器,以确保您有所收获。就我而言,它是与 AMQP 的连接。第一种方法是重写concurrent.futures.Futureresult()方法,强制它返回一个由contextlib.contextmanager修饰的生成器函数。 ajdavis 在他漂亮的库 TORO 中使用了这种方法。您可以通过导航到 this line 来查看它。

但是,如果您不想覆盖 concurrent.futures.Future 对象,那么我建议您执行以下 sn-p:

@gen.coroutine
def ensure_connection(*args, **kwargs):
    res = yield _make_connection(timeout=kwargs.pop('timeout', 5), *args, **kwargs)
    raise gen.Return(res)

@gen.coroutine
def ensure(*args, **kwargs):
    res = yield ensure_connection(*args, **kwargs)

    @contextlib.contextmanager
    def func(res):
       try:
          yield  # your wrapped code
       finally:
          pass

    return func(res)

@gen.coroutine
def simple_usage(conn):
    with (yield conn.ensure()) as res:
        # Do your target staff here

conn = ...
IOLoop.add_callback(callback=lambda : simple_usage(conn))

【讨论】:

  • 我认为应该是:raise gen.Return(func(res)) 而不是 return func(res),除非 Python 3。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-09
  • 1970-01-01
  • 2018-04-21
  • 2014-12-13
  • 1970-01-01
  • 2013-08-24
  • 2020-10-25
相关资源
最近更新 更多