gpt4 book ai didi

python - 协程 vs 延续 vs 生成器

转载 作者:搜寻专家 更新时间:2023-11-01 04:40:51 29 4
gpt4 key购买 nike

协程、延续和生成器之间有什么区别?

最佳答案

我将从生成器开始,因为它们是最简单的情况。正如@zvolkov 提到的,它们是可以重复调用而不返回的函数/对象,但是在调用时将返回(产生)一个值,然后暂停它们的执行。当他们再次被调用时,他们将从他们上次暂停执行的地方开始并再次做他们的事情。

生成器本质上是一个简化的(非对称)协程。协程和生成器之间的区别在于协程可以在初始调用后接受参数,而生成器不能。

想出一个使用协程的简单示例有点困难,但这是我最好的尝试。以这段(编造的)Python 代码为例。

def my_coroutine_body(*args):
while True:
# Do some funky stuff
*args = yield value_im_returning
# Do some more funky stuff

my_coro = make_coroutine(my_coroutine_body)

x = 0
while True:
# The coroutine does some funky stuff to x, and returns a new value.
x = my_coro(x)
print x

使用协程的一个例子是词法分析器和解析器。如果语言中没有协程或以某种方式模拟,词法分析和解析代码需要混合在一起,即使它们实际上是两个独立的问题。但是使用协程,您可以分离出词法分析和解析代码。

(我将重述对称协程和非对称协程之间的区别。只要说它们是等价的就够了,你可以从一个协程转换到另一个协程,而非对称协程——它们最像生成器—— -更容易理解。我概述了如何在 Python 中实现非对称协程。)

Continuation 实际上是非常简单的野兽。它们都是代表程序中另一个点的函数,如果调用它,将导致执行自动切换到该函数代表的点。您每天都在不知不觉中使用它们的非常有限的版本。例如,异常可以被认为是一种由内而外的延续。我将为您提供一个基于 Python 的延续伪代码示例。

假设 Python 有一个名为 callcc() 的函数,这个函数有两个参数,第一个是一个函数,第二个是调用它的参数列表。该函数的唯一限制是它采用的最后一个参数将是一个函数(这将是我们当前的延续)。

def foo(x, y, cc):
cc(max(x, y))

biggest = callcc(foo, [23, 42])
print biggest

会发生的情况是 callcc() 会依次调用带有当前延续 (cc) 的 foo(),即,对程序中调用 callcc() 的点的引用。当 foo() 调用当前延续时,它本质上与告诉 callcc() 返回您正在调用当前延续的值以及它何时返回相同也就是说,它将堆栈回滚到创建当前延续的位置,即当您调用 callcc() 时。

所有这一切的结果是我们假设的 Python 变体将打印 '42'

关于python - 协程 vs 延续 vs 生成器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31875020/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com