python - 协程和生成器之间的差异,Asyncio
问题描述
我正在尝试更多地了解协程以及asyncio
.
据我所知,协程是一个生成器函数。您可以使用async def
. 你可以对生成器函数做的所有事情,你都可以对协程做。你可以做coroutine.send(None)
, coroutine.throw(Exception)
, coroutine.close()
. 现在我有两个关于协程的问题:
当您添加
yield
到函数时,它会成为生成器函数。这意味着您必须在每个生成器中至少包含一次 yield。对于大多数协程(例如在 discord.py 中),我根本看不到 yield 关键字!那么它们是如何生成的呢?也许await
关键字会产生或什么?请解释。如果生成器和协程相同,为什么它们有不同的名称?
现在我想我对生成器函数有了一些了解,它们产生了,你可以向它们发送东西甚至异常。我认为协程是一样的。
所以,我知道这一点:事件循环在看到await
关键字时停止协程(这个关键字只是调用.__await__()
方法)。然后它只执行该关键字之后的函数,然后继续执行不同的任务。很简单。
但我不明白这如何将控制权交还给事件循环。
也许事件循环在运行任务时会这样做:coroutine.send(None)
所以它等到屈服于上下文切换?所以也许等待是一种收益?但是如果它确实产生了,那将使它成为一个生成器方法,并且实际的协程没有产生,但是__await__()
是?
很混乱的东西。有人可以解释什么await
和该方法的.__await__()
作用吗?
所以总结一下我的问题:
- 生成器函数和协程有什么区别?
- 这两者之间有什么不同的用例?
- 它们的工作方式有何不同?
- asyncio 如何在等待之前运行协同程序?
- 方法有什么作用
__await__()
? - 为什么我在协程中看不到任何收益?
解决方案
推荐阅读
- laravel - 通过 Redis 在多个服务器上的 Laravel 事件监听器
- excel-dna - 如何获取数组函数中每个单元格的单元格地址?
- websocket - 我们是否必须为 Signalr 使用 Websocket Sampler。这是 JMeter 中的义务还是建议?
- google-cloud-platform - GCP 悉尼地区的 Cloud Task 连接速度非常慢
- c# - 成瘾问题
- python - 仅使用 glob 搜索多个模式一次
- java - JPA 更新对象在多对多关系中创建一个新对象
- git - Git 不断启动浏览器进行身份验证
- r - 如何将数据框的观察结果按 3 分组?
- parallel-processing - 模型在分布式数据并行的情况下占用两倍的内存空间