【问题标题】:Why do we need coroutines in python? [closed]为什么我们需要 python 中的协程? [关闭]
【发布时间】:2017-04-16 23:39:33
【问题描述】:

我很久以前就听说过协同程序,但从未使用过它们。据我所知,协程类似于生成器。

为什么我们需要 Python 中的协程?

【问题讨论】:

  • 您应该能够使用谷歌找到答案。这里的任何答案都可能是主观的和冗长的。这就是为什么这些问题被认为是 SO 的题外话。
  • 我同意。我想要一个可以使用它的真实示例。
  • 我认为 David Beasley (dabeaz) 是 python 中协程的主要支持者之一。他的博客或 pycon 演讲可能是一个不错的起点。
  • 它们是解决问题的另一个有用工具。

标签: python coroutine


【解决方案1】:

Generator 使用 yield 来返回值。 Python 生成器函数还可以使用 (yield) 语句来使用值。此外,生成器对象的两个新方法send()close() 为消费和产生值的对象创建了一个框架。定义这些对象的生成器函数称为coroutines

协程使用(yield) 语句来使用值,如下所示:

value = (yield)

使用此语法,执行会在此语句处暂停,直到使用参数调用对象的发送方法:

coroutine.send(data)

然后,继续执行,将值分配给数据的值。为了表示计算结束,我们使用close() 方法关闭了一个协程。这会在协程内引发 GeneratorExit 异常,我们可以使用 try/except 子句捕获。

以下示例说明了这些概念。它是一个协程,打印与提供的模式匹配的字符串。

def match(pattern):
    print('Looking for ' + pattern)
    try:
        while True:
            s = (yield)
            if pattern in s:
                print(s)
    except GeneratorExit:
        print("=== Done ===")

我们用一个模式初始化它,然后调用__next__()开始执行:

m = match("Jabberwock")
m.__next__()
Looking for Jabberwock

__next__() 的调用导致函数体被执行,因此“寻找jabberwock”行被打印出来。继续执行直到遇到语句line = (yield)。然后,执行暂停,并等待一个值被发送到 m。我们可以使用send() 向它发送值。

【讨论】:

  • 我喜欢你的帖子,但也许它也可以详细说明为什么/何时它们比函数或对象更好?
  • 如果你使用@coroutine 装饰你的函数,你也可以省略 m.__next__() 调用,这里简要描述了dabeaz.com/coroutines/coroutine.py
  • 您能详细说明 _next__() 吗?我的问题是,为什么python在达到yield之前不执行该函数?是什么触发了这种行为? python 是否正在扫描整个函数并检查它是否看到'yield',然后确定 match("") 不是函数调用,而是某种闭包?我有点疑惑。
  • 你没有提到我们何时以及为什么使用协程?你只是给出了执行它们的步骤..
【解决方案2】:

协程类似于生成器,但有一些区别。主要区别在于:

  1. 生成器是数据生产者
  2. 协程是数据消费者

You may have a look here for details

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-27
    • 1970-01-01
    • 2016-09-24
    • 1970-01-01
    • 2013-05-14
    • 1970-01-01
    相关资源
    最近更新 更多