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产生价值1的next回归,然后阻塞,直到下一个进入发电机。由第二次调用产生的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表达式之间的细微差别。
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中的语句之间有什么区别?