我一直在使用 py3.4 的基于生成器的协程,并且在几个地方我通过简单地进行一个协程调用来链接它们return inner_coroutine()
(如下例所示)。但是,我现在将它们转换为使用 py3.5 的本机协程,并且我发现它不再起作用,因为内部协程无法运行(请参阅运行下面示例的输出)。为了运行本机内部协程,我需要使用return await inner_coroutine()
而不是原来的return inner_coroutine()
.
我希望本机协程的链接能够以与基于生成器的协程相同的方式工作,并且找不到任何其他说明的文档。我是否遗漏了什么或者这是本机协程的实际限制?
import asyncio
@asyncio.coroutine
def coro():
print("Inside coro")
@asyncio.coroutine
def outer_coro():
print("Inside outer_coro")
return coro()
async def native_coro():
print("Inside native_coro")
async def native_outer_coro():
print("Inside native_outer_coro")
# return await native_coro() # this works!
return native_coro()
loop = asyncio.get_event_loop()
loop.run_until_complete(outer_coro())
loop.run_until_complete(native_outer_coro())
以及运行该示例的输出:
Inside outer_coro
Inside coro
Inside native_outer_coro
foo.py:26: RuntimeWarning: coroutine 'native_coro' was never awaited
loop.run_until_complete(native_outer_coro())
这与另一个答案的内容相同,但以我认为作为对问题的回答更容易理解的方式表述。
python 判断某个东西是生成器还是普通函数的方法是看它是否包含yield
陈述。
这会产生歧义@asyncio.coroutine
。
你的协程是立即执行还是等待调用者调用next
生成的生成器对象取决于您的代码是否实际上碰巧包含yield statement
。
本机协程在设计上明确是生成器,即使它们不碰巧包含任何等待语句。
这提供了可预测的行为,但不允许您使用的链接形式。
你可以像你指出的那样
return await inner_coroutine()
但请注意,在该等待语法中,在事件循环中执行外部协程时会调用内部协程。然而,使用基于生成器的方法并且没有yield,内部协程是在实际将协程提交到事件循环时构建的。
在大多数情况下,这种差异并不重要。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)