您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

Python原生协程和send()

Python原生协程和send()

有没有办法从中断的地方恢复返回的协程并可能发送新值?

没有。

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是不建议使用的。如果您想要的协程根本不与事件循环绑定,请改用它。asyncawait专门为事件循环异步编程设计。如果这不是你在做什么,然后asyncawait都开始与错误的工具。

还有一件事:

yield明确禁止在异步函数中使用in,因此本机协程只能使用一条return语句返回一次。

await表达式 可以 控制产量。 await something()完全类似于yield from something()。他们只是更改了名称,所以对于不熟悉发电机的人来说将更加直观。

对于那些实际上对实现自己的事件循环感兴趣的人,这里有一些示例代码,展示了(非常少的)实现。此事件循环极为简化,因为它被设计为同步运行某些特殊编写的协程,就像它们是正常功能一样。它不能提供您期望从真正的BaseEventLoop实现中获得的全面支持,并且对于与任意协程一起使用也不安全。

通常,我会将代码包含在我的答案中,而不是链接到该代码,但是存在版权问题,它对答案本身并不重要。

python 2022/1/1 18:26:22 有183人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶