首页 文章

用Python 3.3中的新生成器调用gen.send()?

提问于
浏览
0

来自PEP342

因为生成器迭代器在生成器函数体的顶部开始执行,所以在刚刚创建生成器时没有yield表达式来接收值 . 因此,当生成器迭代器刚刚启动时,禁止使用非None参数调用send(),...

例如,

>>> def a():
...     for i in range(5):
...         print((yield i))
... 
>>> g = a()
>>> g.send("Illegal")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't send non-None value to a just-started generator

为什么这是非法的?我在这里理解了 yield 的使用方式,它暂停了函数的执行,并在下次调用 next() (或 send() )时返回到该位置 . 但似乎打印 (yield i) 的第一个结果应该是合法的?

问一个不同的方式,在 g = a() 后直接在什么状态下发电机'g' . 我假设它已经运行 a() 直到第一次收益,并且因为有一个收益它返回一个生成器,而不是标准的同步对象返回 .

So why exactly is calling send with non-None argument on a new generator illegal?

注意:我已经阅读了this question的答案,但是在新的生成器上调用send(带有非None)并不是非法的't really get to the heart of why it' .

1 回答

  • 2

    问一个不同的方式,在g = a()之后,发电机'g'处于什么状态 . 我假设它已经运行了一个()直到第一次产生,并且因为有一个yield它返回一个生成器,而不是标准的同步对象返回 .

    g = a() 之后,它正好在函数的开头 . 在您将发电机推进一次之后(通过调用 next(g) ),它不会达到第一次产量 .

    这就是你在问题中包含的引用中所说的内容:"Because generator-iterators begin execution at the top of the generator's function body..."它也在PEP 255中说明了它引入了生成器:

    当调用生成器函数时,实际参数以通常的方式绑定到函数本地形式参数名称,但不执行函数体中的代码 .

    请注意,yield语句是否实际执行并不重要 . 仅仅在函数体内出现 yield 就会使函数成为生成器,如documented

    在函数定义中使用yield表达式足以使该定义创建生成器函数而不是正常函数 .

相关问题