V2EX 首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  程序员

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

  •  
  •   zjsxwc · 35 天前 · 1972 次点击
    这是一个创建于 35 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

    你们怎么看?

    17 回复  |  直到 2017-10-15 16:11:24 +08:00
        1
    sunjourney   35 天前
    这取决于你怎么 yield,你既可以 yield 符合调度器协议的东西,也可以不,但你总归需要去调试它,要么自动(携协),要么手动。
        2
    sunjourney   35 天前
    携协 -> 协程

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

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

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

    当然,内部实现还是差不多的。
        13
    QAPTEAWH   34 天前 via iPhone
    背后的原理是一样的( continuation )
        14
    gouchaoer   34 天前 via Android
    写起来很麻烦,还是全协程好用
        15
    chengluyu   34 天前
    协程怎么和 goto 划等号的……
        16
    ivechan   34 天前
    "The yield expression is used when defining a generator function or an asynchronous generator"
    "A Python generator is a form of coroutine,"
    说白了 generator 其实也是一种 coroutine。
        17
    sexrobot   33 天前
    http://www.laruence.com/2015/05/28/3038.html
    yield 的造物主都这么用了.
    DigitalOcean
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   鸣谢   ·   1597 人在线   最高记录 3541   ·  
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.0 · 58ms · UTC 06:36 · PVG 14:36 · LAX 22:36 · JFK 01:36
    ♥ Do have faith in what you're doing.
    沪ICP备16043287号-1