有没有办法从中断的地方恢复返回的协程并可能发送新值?
没有。
async
并且await
是 刚 句法糖yield from
。当协程返回(带有return
语句)时,就是这样。框架不见了。它不可恢复。这正是发电机始终工作的方式。例如:
def foo():
return (yield)
您可以这样做f = foo(); next(f); f.send(5)
,然后您将返回5。但是,如果f.send()
再次尝试,它将不起作用,因为您已经从框架中返回了。 f
不再是现场发电机。
现在,就新的协程而言,据我所知,似乎在事件循环与某些基本谓词(例如)之间的通信中保留了yield和sendasyncio.sleep()
。协程产生asyncio.Future
直到事件循环的对象,并且一旦关联操作完成(它们通常通过call_soon()
和其他事件循环方法进行调度),事件循环会将那些相同的将来对象发送回协程。
您可以通过等待它们来产生将来的对象,但这不是像.send()
was那样的通用接口。它专门供事件循环实现使用。如果您没有实现事件循环,则可能不想玩这个循环。如果您正在 实现一个事件循环,你需要问自己为什么完美的实现中asyncio
不足以达到你的目的,并解释 明确 你正在尝试做之前,我们可以帮助你。
请注意,这yield from
是不建议使用的。如果您想要的协程根本不与事件循环绑定,请改用它。async
并await
在专门为事件循环异步编程设计。如果这不是你在做什么,然后async
和await
都开始与错误的工具。
还有一件事:
yield
明确禁止在异步函数中使用in,因此本机协程只能使用一条return
语句返回一次。
await
表达式 可以 控制产量。 await something()
完全类似于yield from something()
。他们只是更改了名称,所以对于不熟悉发电机的人来说将更加直观。
对于那些实际上对实现自己的事件循环感兴趣的人,这里有一些示例代码,展示了(非常少的)实现。此事件循环极为简化,因为它被设计为同步运行某些特殊编写的协程,就像它们是正常功能一样。它不能提供您期望从真正的BaseEventLoop实现中获得的全面支持,并且对于与任意协程一起使用也不安全。