生成器函数在内部是如何工作的?
How does a generator function work internally?
下面是生成器函数。
def f():
x=1
while 1:
y = yield x
x += y
这个生成器函数 (f
) 是否在内部实现,如下所示?
class f(collections.Iterable):
def __init__(self):
self.x = 1
def __iter__(self):
return iter(self)
def __next__(self):
return self.x
def send(self, y):
self.x += y
return self.next()
编辑:
是我问题的答案。
在内部,生成器的工作方式与常规函数调用大致相同。在引擎盖下,运行 生成器和 运行 函数主要使用相同的机制。
当您调用函数或生成器时,会创建堆栈框架。它具有局部变量(包括传递给函数的参数)、指向活动操作码的代码指针以及用于挂起的 try 块、with 块或循环的堆栈。
在常规函数中,执行会立即开始。当遇到 return
时,保留最终结果并释放堆栈帧及其引用的所有内容。
中遇到generator function, the stackframe is wrapped in a generator-iterator object and returned immediately. The code in the generator function only runs when called by next(g)
or g.send(v)
. Execution is suspended when yield
理解生成器的一种方式是,它们就像可以用 yield
暂停并用 g.next()
恢复的函数。 stackframe 保持活动状态,因此恢复 运行 生成器 比每次调用都必须构建新框架的新函数调用便宜 很多 。
下面是生成器函数。
def f():
x=1
while 1:
y = yield x
x += y
这个生成器函数 (f
) 是否在内部实现,如下所示?
class f(collections.Iterable):
def __init__(self):
self.x = 1
def __iter__(self):
return iter(self)
def __next__(self):
return self.x
def send(self, y):
self.x += y
return self.next()
编辑:
在内部,生成器的工作方式与常规函数调用大致相同。在引擎盖下,运行 生成器和 运行 函数主要使用相同的机制。
当您调用函数或生成器时,会创建堆栈框架。它具有局部变量(包括传递给函数的参数)、指向活动操作码的代码指针以及用于挂起的 try 块、with 块或循环的堆栈。
在常规函数中,执行会立即开始。当遇到 return
时,保留最终结果并释放堆栈帧及其引用的所有内容。
中遇到generator function, the stackframe is wrapped in a generator-iterator object and returned immediately. The code in the generator function only runs when called by next(g)
or g.send(v)
. Execution is suspended when yield
理解生成器的一种方式是,它们就像可以用 yield
暂停并用 g.next()
恢复的函数。 stackframe 保持活动状态,因此恢复 运行 生成器 比每次调用都必须构建新框架的新函数调用便宜 很多 。