在 Python 3.3+ 中使用新生成器调用 gen.send()?

Calling gen.send() with a new generator in Python 3.3+?

来自 PEP342:

Because generator-iterators begin execution at the top of the generator's function body, there is no yield expression to receive a value when the generator has just been created. Therefore, calling send() with a non-None argument is prohibited when the generator iterator has just started, ...

例如,

>>> 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 的方式,它会暂停函数的执行,并且 return 会在下次调用 next()(或 send())时到达那个位置.但是打印 (yield i)?

的第一个结果似乎应该是合法的

换一种方式问,g = a() 之后的生成器 'g' 处于什么状态。我假设它有 运行 a() 直到第一个 yield,并且因为有一个 yield 它 returned 一个生成器,而不是一个标准的同步对象 return.

那么,为什么在新生成器上使用非 None 参数调用 send 是非法的?

注意:我已经阅读了 this question 的答案,但它并没有真正理解为什么在新的网络上调用发送(非 None)是非法的发电机。

Asked a different way, in what state is the generator 'g' directly after g = a(). I assumed that it had run a() up until the first yield, and since there was a yield it returned a generator, instead of a standard synchronous object return.

没有。在 g = a() 之后,它就在函数的开头。它不会 运行 直到你将生成器推进一次(通过调用 next(g))。

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

When a generator function is called, the actual arguments are bound to function-local formal argument names in the usual way, but no code in the body of the function is executed.

注意yield语句是否真正执行并不重要。仅仅在函数体内出现 yield 就使函数成为生成器,如 documented:

Using a yield expression in a function definition is sufficient to cause that definition to create a generator function instead of a normal function.