从coroutine直接调用Python的协程

Direct call Python's coroutine from coroutine

我正在创建一个简单的 class 和 API 复杂的 class。 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)

从外部 class 我仍然想调用协程之类的方法,例如

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

现在我想从 simple1simple2 调用中删除 await 因为我想防止跳转到事件循环并返回(感觉就像浪费时间简单的调用)。

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

你可以直接return调用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() 方法主体,而不是生成一个包装器,然后推迟到相同的。

但是,asyncawait 关键字的添加使得 代码的 reader 清楚这些方法产生的 协程。开销很小,考虑保留它们。