【发布时间】: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