从协程直接调用Python的协同程序

时间:2017-07-04 09:32:53

标签: python python-3.x coroutine

我正在创建一个简单而复杂的API类。作为此API的一部分的每个方法都应该是协同的。让我们说它看起来像这样:

class MyClass:
    async def complex(self, **kwargs):
        x = compute(kwargs)
        return await asyncio.sleep(x)

    async def simple1(self, param):
        return await self.complex(a=param, b=None)

    async def simple2(self, param):
        return await self.complex(a=None, b=param)

从这个课程的外部我仍然想要像协程一样调用方法,例如

x = MyClass()
loop = asyncio.get_event_loop()
result = loop.run_until_complete(x.simple1(42))

现在我想从awaitsimple1调用中删除simple2,因为我想阻止跳转到事件循环和返回(感觉就像是为了简单的调用而浪费时间)。

有什么办法可以做到这一点吗?当然,任何解决方案都不应超过await方法的开销。

1 个答案:

答案 0 :(得分:3)

您只需返回调用self.complex()直接生成 的协同例程:

class MyClass:
    async def complex(self, **kwargs):
        x = compute(kwargs)
        return await asyncio.sleep(x)

    def simple1(self, param):
        return self.complex(a=param, b=None)

    def simple2(self, param):
        return self.complex(a=None, b=param)

这会将complex()协同例程直接传递给调用者。

毕竟,MyClass().complex()所做的就是为延迟执行生成一个协程对象。同一个对象可以通过其他同步调用传递,调用MyClass().simple1('foo')现在恰好创建一个不同的协同程序对象,它直接执行complex()方法体,而不是生成一个随后推迟的包装器。 / p>

但是,添加asyncawait关键字使代码的读者明白这些方法可以生成协同例程。开销很小,请考虑保留它们。