目前,我正在尝试理解Python如何实现yield
和生成器。在文档上说
通过挂起,我们的意思是保留所有本地状态,包括局部变量的当前绑定,指令指针,内部评估堆栈以及任何异常处理的状态。当通过调用生成器的一个方法恢复执行时,该函数可以完全像yield表达式只是另一个外部调用一样。
这对我来说似乎非常违反直觉,因为我所知道的所有函数调用方案都是基于堆栈的,例如C调用约定。我真的很好奇Python如何存储功能的所有状态以及执行流程如何回到yield
之后的位置。
最后一个问题是,是否有任何算法可以从任意生成器函数派生生成器迭代器的实现。例如,假设我们有一个生成器函数:
def generator_f():
for i in range(10):
yield i
for i in range(10):
yield i
我们能系统地实现一个迭代器,它在功能上等同于generator_f()
返回的生成器迭代器吗?功能上我指的是行为和(记忆)效率。
您可以在cpython/Lib/asyncio/coroutines.py
中看到Cpython如何实现协同程序。要了解如何实现生成器,请参阅cpython/Objects/genobject.c
。具体来说,yield from
背后的逻辑可以在函数gen_getyieldfrom()
和_PyGen_yf()
中找到。
关于你关于等效迭代器的问题:
iter([*range(10), *range(10)])