gpt4 book ai didi

python - 试图将 yield 理解为一个表达式

转载 作者:太空狗 更新时间:2023-10-30 00:57:00 25 4
gpt4 key购买 nike

我正在研究生成器和生成器表达式,但我不确定我是否理解它们的工作原理 (some reference material):

>>> a = (x for x in range(10))
>>> next(a)
0
>>> next(a)
1
>>> a.send(-1)
2
>>> next(a)
3

所以看起来 generator.send 被忽略了。这是有道理的(我猜),因为没有明确的 yield 表达式来捕获发送的信息......

但是,

>>> a = ((yield x) for x in range(10))
>>> next(a)
0
>>> print next(a)
None
>>> print next(a)
1
>>> print next(a)
None
>>> a.send(-1) #this send is ignored, Why? ... there's a yield to catch it...
2
>>> print next(a)
None
>>> print next(a)
3
>>> a.send(-1) #this send isn't ignored
-1

我知道这还很遥远,我(目前)想不出一个用例(所以不要问;)

我主要只是在探索,试图弄清楚这些不同的生成器方法是如何工作的(以及生成器表达式通常是如何工作的)。为什么我的第二个示例在产生合理值和 None 之间交替?另外,谁能解释为什么我的 generator.send 中的一个被忽略而另一个没有被忽略?

最佳答案

这里的混淆是生成器表达式正在执行隐藏的 yield。这是函数形式:

def foo():
for x in range(10):
yield (yield x)

当您执行 .send() 时,会执行内部 yield x,从而产生 x。然后表达式求值为 .send 的值,下一个 yield 产生它。这是更清晰的形式:

def foo():
for x in range(10):
sent_value = (yield x)
yield sent_value

因此输出是非常可预测的:

>>> a = foo()
#start it off
>>> a.next()
0
#execution has now paused at "sent_value = ?"
#now we fill in the "?". whatever we send here will be immediately yielded.
>>> a.send("yieldnow")
'yieldnow'
#execution is now paused at the 'yield sent_value' expression
#as this is not assigned to anything, whatever is sent now will be lost
>>> a.send("this is lost")
1
#now we're back where we were at the 'yieldnow' point of the code
>>> a.send("yieldnow")
'yieldnow'
#etc, the loop continues
>>> a.send("this is lost")
2
>>> a.send("yieldnow")
'yieldnow'
>>> a.send("this is lost")
3
>>> a.send("yieldnow")
'yieldnow'

编辑:用法示例。到目前为止,我见过的最酷的是 twisted 的 inlineCallbacks 函数。 See here一篇解释它的文章。它的核心是它让你产生函数在线程中运行,一旦函数完成,twisted 将函数的结果发送回你的代码。因此,您可以以非常线性和直观的方式编写严重依赖线程的代码,而不必在各处编写大量的小函数。

参见 PEP 342有关让 .send 处理潜在用例的基本原理的更多信息(我提供的扭曲示例是此更改提供的异步 I/O 好处的示例)。

关于python - 试图将 yield 理解为一个表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12324096/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com