yield 明明是用来做生成器 generator 的, 为什么好多人要用来做"协程"?

2017-10-14 13:31:19 +08:00
 zjsxwc

yield 本意作为 generator 是很方便的,但好多人要用来做"协程"...

这种 yield 做"协程"的方式,让我想到了当年 C 里的 goto 语句, 把代码写到很混乱, 明明是种反模式, 却会被人追捧.

你们怎么看?

3663 次点击
所在节点    程序员
17 条回复
sunjourney
2017-10-14 13:49:06 +08:00
这取决于你怎么 yield,你既可以 yield 符合调度器协议的东西,也可以不,但你总归需要去调试它,要么自动(携协),要么手动。
sunjourney
2017-10-14 13:49:31 +08:00
携协 -> 协程

手快了
kindjeff
2017-10-14 13:50:38 +08:00
啥叫好多人,官方不都这么做了么。
GeruzoniAnsasu
2017-10-14 13:51:04 +08:00
不是 yield 用来做协程
首先你要明白协程解决了什么问题
在异步模式下,传统的解决方式是用各种回调来处理异步 IO 的结果,当 IO 完成时产生事件并由回调去处理事件
然而这样的模式 io 发起代码和回调无法写在一起,当异步操作多了之后回调大量增加代码可读性会急剧下降
而采用协程的模式,发起请求和回调处理写在一起就像一个普通的 block 线程一样
发起 io 时 yield 出当前函数,当请求完成后由调度器调度回本函数继续在 yield 的位置往下执行,结构就简单清晰很多
并不是 yield 做协程,而是协程模式必须要有 yield 才可能实现
hjc4869
2017-10-14 13:52:45 +08:00
问题是 coroutine 代码一点都不混乱,可读性比别的写法强啊(
hjc4869
2017-10-14 13:53:16 +08:00
coroutine 做得好的比如 C#,你把 async await 关键字和方法签名里的 Async 后缀忽略掉,就跟同步阻塞的程序没有什么区别了。
beginor
2017-10-14 14:06:34 +08:00
@hjc4869 async 和 await 最早出现在 F#中,巨硬觉得这个比较屌,可以甩 Java 多少年,可是 F#始终是少数派中的少数派,最终移值到了 C#
NoAnyLove
2017-10-14 14:29:01 +08:00
那是因为 Guido 对于添加关键字过于谨慎了,不过在后来的版本中还是加入了 async 和 await 关键字。另外,Python 的 coroutine 就是在 generator 之上发展出来的,事实上在官方支持 coroutine 之前,第三方的库就基于 generator 实现了 coroutine,所以也可以说是历史遗留问题。

最后,yield 的语法用于 coroutine 并没有觉得凌乱,虽然有可能让人不能一下区分一个函数到底是 coroutine 还是 generator ;另外,goto 虽然被认为是经典的反例,但其实是被过度宣传了,在适合它的场景中,goto 是非常好用的。
hcnhcn012
2017-10-14 14:41:55 +08:00
。。。完成协程还有比 yield 更 python 的特性么?
geelaw
2017-10-14 14:51:25 +08:00
呃……迭代器不是 coroutine 的一个例子么?

我更感兴趣为什么要造出 coroutine 这个名词,因为从形式上来说 subroutine 更简单,并且 coroutine 就是保存了调用栈的、多次运行第一步是跳转到上次结束位置之后的一段构造。或许对于 programming 的 philosophy 是有好处的吧。
jiangzhuo
2017-10-14 14:57:06 +08:00
这事你得问 tj
ipwx
2017-10-14 15:10:07 +08:00
你可以选择 Python 3.5+,有 async await 替代历史遗留的 @coroutine 和 yield from。

当然,内部实现还是差不多的。
QAPTEAWH
2017-10-14 16:42:59 +08:00
背后的原理是一样的( continuation )
gouchaoer
2017-10-14 17:09:32 +08:00
写起来很麻烦,还是全协程好用
chengluyu
2017-10-15 00:04:49 +08:00
协程怎么和 goto 划等号的……
ivechan
2017-10-15 09:15:23 +08:00
"The yield expression is used when defining a generator function or an asynchronous generator"
"A Python generator is a form of coroutine,"
说白了 generator 其实也是一种 coroutine。
sexrobot
2017-10-15 16:11:24 +08:00
http://www.laruence.com/2015/05/28/3038.html
yield 的造物主都这么用了.

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/397565

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX