生成器功能如何在内部工作? [英] How does a generator function work internally?

查看:43
本文介绍了生成器功能如何在内部工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是一个生成器函数.

Below is a generator function.

def f():
   x=1
   while 1:
      y = yield x
      x += y

此生成器函数(f)是否在内部实现,如下所示?

Does this generator function (f) get implemented, internally, as shown below?

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()

是我的问题的答案. /p>

This is the answer for my question.

推荐答案

在内部,生成器的工作原理与常规函数调用大致相同.在引擎盖下,正在运行的发电机和正在运行的功能大多使用相同的机器.

Internally, a generator works about the same as a regular function call. Under-the-hood, running generators and running functions use mostly the same machinery.

调用函数或生成器时,将创建一个堆栈框架.它具有局部变量(包括传递到函数中的参数),指向活动操作码的代码指针,以及用于暂挂try-block,with-blocks或loops的堆栈.

When you call either a function or a generator, a stackframe is created. It has the local variables (including the arguments passed into the function), a code pointer to the active opcode, and a stack for pending try-blocks, with-blocks, or loops.

在常规函数中,执行立即开始.当遇到 return 时,将保留最终结果并保留堆栈框架随其引用的所有内容一起释放.

In a regular function, execution begins immediately. When return is encountered, the final result is kept and the stackframe is freed along with everything it referenced.

生成器函数中,堆栈框架包装在<一个href ="https://docs.python.org/3/glossary.html#term-generator-iterator" rel ="noreferrer"> generator-iterator 对象,并立即返回.生成器函数中的代码仅在被next(g)g.send(v)调用时运行.遇到 yield 时,执行将暂停.

In a 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 is encountered.

想到生成器的一种方法是,它们就像可以通过yield暂停并通过g.next()恢复的函数一样.堆栈框架保持活动状态,因此恢复运行中的生成器比进行新的函数调用要便宜得多,新的函数调用必须在每次调用时都建立一个新的框架.

One way to think of generators is that they are like functions that can be paused with yield and resumed with g.next(). The stackframe is kept alive, so resuming a running generator is much cheaper than making a new function call which has to build a new frame on every invocation.

这篇关于生成器功能如何在内部工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆