什么时候使用return(产生一些东西)? [英] When to use return (yield something)?

查看:108
本文介绍了什么时候使用return(产生一些东西)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

很长时间以来,我不知道您不能将return放在yield语句的前面.但实际上您可以:

For a long time I didn't know you can't put return in front of a yield statement. But actually you can:

def gen():
    return (yield 42)

类似于

def gen():
    yield 42
    return

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

And the only usage I can think of is to attach sent value to StopIteration: pep-0380

生成器中的return expr导致StopIteration(expr)升高 从发电机退出后.

return expr in a generator causes StopIteration(expr) to be raised upon exit from the generator.

def gen():
    return (yield 42)

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

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

But this can be done using an extra variable too, which is more explicit:

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)仅仅是一种语法糖.我想念什么吗?

So it seems return (yield xxx) is merely a syntactic sugar. Am I missing something?

推荐答案

在生成器中,表达式(收益率42)将产生值42,但如果使用next(generator),则返回的值将为None(无).如果使用generator.send(value),则为给定值.

Inside a generator the expressions (yield 42) will yield the value 42, but it also returns a value which is either None, if you use next(generator) or a given value if you use generator.send(value).

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

So as you say, you could use an intermediate value to get the same behavior, not because this is syntactical sugar, but because the yield expressions is literally returning the value you send it.

您同样可以做类似的事情

You could equally do something like

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

如果我们通过调用顺序来调用它:

If we call this, using the sequence of calls:

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),因为在生成器中处理返回的方式. 因此,由于异常,您永远都不会到达第三次发送.

First we get the output of 42, and the generator is essentially paused in a state you could describe like: return (yield <Input will go here> + 10), If we then call g.send(1) we get the output 11. and the generator is now in the state: return <Input will go here>, then sending g.send(22) will throw a StopIteration(22), because of the way return is handled in generators. So you never get to the third send because of the exception.

我希望这个例子可以使yield在生成器中的工作方式更加清晰,以及为什么return (yield something)语法没有什么特殊或异国情调,并且能按您期望的方式工作.

I hope this example makes it a bit more apparent how yield works in generators and why the syntax return (yield something) is nothing special or exotic and works exactly how you'd expect it.

至于字面上的问题,您何时才能执行此操作?好吧,无论何时您想产生一些东西,然后在以后返回一个StopIteration,以回显发送给生成器的用户输入.因为这实际上就是代码要说明的内容.我希望很少有人想要这样的行为.

As for the literal question, when would you do this? Well when ever you want to yield something, and then later return a StopIteration echoing the input of the user sent to the generator. Because this is literally what the code is stating. I expect that such behavior is very rarely wanted.

这篇关于什么时候使用return(产生一些东西)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆