何时使用return(收益)



很长一段时间以来,我都不知道不能将return放在yield语句前面。但实际上你可以:

def gen():
return (yield 42)

类似于

def gen():
yield 42
return

我能想到的唯一用法是将发送值附加到StopIteration:pep-0380

在生成器中返回expr会导致StopIteration(expr)被引发在离开发电机时。

def gen():
return (yield 42)
g = gen()
print(next(g))  # 42
try:
g.send('AAAA')
except StopIteration as e:
print(e.value)  # 'AAAA'

但这也可以使用一个额外的变量来完成,这个变量更明确:

def gen():
a = yield 42
return a
g = gen()
print(next(g))
try:
g.send('AAAA')
except StopIteration as e:
print(e.value)  # 'AAAA'

因此,return (yield xxx)似乎只是一种句法糖。我是不是错过了什么?

在生成器内部,表达式(yield 42)将生成值42,但如果使用next(generator),它也会返回一个None值,如果使用generator.send(value),则返回一个给定值。

正如你所说,你可以使用一个中间值来获得相同的行为,不是因为这是语法上的糖,而是因为yield表达式实际上是在返回你发送的值

你同样可以做一些类似的事情

def my_generator():
return (yield (yield 42) + 10)

如果我们调用这个,使用调用序列:

g = my_generator()
print(next(g))
try:
print('first response:', g.send(1))
print('Second response:', g.send(22))
print('third response:', g.send(3))
except StopIteration as e:
print('stopped at', e.value)

首先,我们得到42的输出,生成器基本上处于暂停状态,您可以描述为:return (yield <Input will go here> + 10),如果我们调用g.send(1),我们得到输出11。并且发电机现在处于以下状态:return <Input will go here>,然后发送g.send(22)将抛出StopIteration(22),这是因为生成器中处理返回的方式。因此,由于出现异常,您永远无法进行第三次发送。

我希望这个例子能让我们更清楚地了解yield是如何在生成器中工作的,以及为什么return (yield something)语法没有什么特别或奇特之处,并且完全按照您的预期工作

至于字面上的问题,你什么时候会这样做?好吧,当你想要产生一些东西,然后稍后返回一个StopIteration,以响应用户发送给生成器的输入。因为这就是代码的字面意思。我预计这种行为很少被人想要。

最新更新