收益内的收益有什么作用?

Dav*_*vid 56 python yield python-3.x

考虑以下代码:

def mygen():
     yield (yield 1)
a = mygen()
print(next(a))
print(next(a)) 
Run Code Online (Sandbox Code Playgroud)

输出结果:

1
None
Run Code Online (Sandbox Code Playgroud)

口译员到底在“外部”做什么?

che*_*ner 49

a是一个生成器对象。第一次调用next它时,主体将被评估为第一个yield表达式(即第一个要评估的表达式:内部表达式)。这yield产生价值1next回归,然后阻塞,直到下一个进入发电机。由第二次调用产生的next,这并没有发送任何值所述发电机。结果,第一个(内部)yield计算为None。该值用作外部变量的参数yield,它成为对的第二次调用的返回值next。如果您next第三次打电话,您将获得一个StopIteration例外。

比较send方法的使用(而不是next)来更改第一个yield表达式的返回值。

>>> a = mygen()
>>> next(a)
1
>>> a.send(3)  # instead of next(a)
3
>>> next(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
Run Code Online (Sandbox Code Playgroud)

编写生成器的更明确的方式是

def mygen():
    x = yield 1
    yield x

a = mygen()
print(a.send(None))  # outputs 1, from yield 1
print(a.send(5))     # makes yield 1 == 5, then gets 5 back from yield x
print(a.send(3))     # Raises StopIteration, as there's nothing after yield x
Run Code Online (Sandbox Code Playgroud)

在Python 2.5之前的版本中,该yield 语句提供了调用者和生成器之间的单向通信。调用next将执行生成器,直到下一条yield语句为止,而yield关键字提供的值将作为的返回值next。生成器还将在yield语句的点处挂起,等待下一个调用next恢复。

在Python 2.5时,yield语句置换*与yield 表达,和发电机获取的send方法。send的工作方式非常类似于next,但可以接受一个参数。(对于其余部分,假定next(a)等效于a.send(None)。)生成器在调用之后开始执行send(None),此时它执行直到第一个生成为止yield,该生成器将像以前一样返回一个值。不过,现在表达式将一直阻塞,直到下一次调用send,此时yield表达式的计算结果将是传递给的参数send。生成器现在可以在恢复时接收值。


*尚未完全取代;kojiro的答案更详细地说明了yield语句和yield表达式之间的细微差别。

  • 您似乎在用“第一”来表示“内部”。尽管内部“收益率”首先被“评估”,但其次是“书面”被评估,因此我认为术语令人困惑。另外,我假设“发电机”是指“发电机”。 (3认同)

koj*_*iro 25

yield有两种形式,表达式和语句。它们基本上是相同的,但我最经常statement以不使用结果的形式查看它们。

def f():
    yield a thing
Run Code Online (Sandbox Code Playgroud)

但是在表达式形式中,yield具有一个值:

def f():
    y = yield a thing
Run Code Online (Sandbox Code Playgroud)

在您的问题中,您同时使用两种形式:

def f():
    yield ( # statement
        yield 1 # expression
    )
Run Code Online (Sandbox Code Playgroud)

迭代生成的生成器时,首先将获得内部yield表达式的结果

>>> x=f()
>>> next(x)
1
Run Code Online (Sandbox Code Playgroud)

此时,内部表达式还产生了一个值,外部语句可以使用该值

>>> next(x)
>>>  # None
Run Code Online (Sandbox Code Playgroud)

现在您已经用尽了发电机

>>> next(x)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
Run Code Online (Sandbox Code Playgroud)

要了解有关语句和表达式的更多信息,在其他stackoverflow问题中也有很好的答案:表达式和Python中的语句之间有什么区别?