【问题标题】:Generator with return statement [duplicate]带有返回语句的生成器[重复]
【发布时间】:2016-10-06 06:37:35
【问题描述】:

在我的报道中,我对以下案例(python 3.4)摸不着头脑

def simple_gen_function(str_in, sep=""):
    if sep == "":
        yield str_in[0]
        for c in str_in[1:]:
            yield c
    else:
        return str_in
        # yield from str_in

str_in = "je teste "
t = "".join(simple_gen_function(str_in))
p = "".join(simple_gen_function(str_in, "\n"))

print("%r %r" % (t, p))
# 'je teste' ''

在生成器中使用 return 时,使用 yield from str_in 时没有“达到”返回值我得到了预期的结果。

这个问题看起来很简单,但我相信在生成器中使用 return 就可以了。

【问题讨论】:

  • return 在生成器中的行为与普通函数不同,它是在生成器完成时引发的 StopIteration 中的值,yield 的函数不能只返回一个value 相反,您将需要生成器作为辅助函数,另一个返回未更改的字符串或返回生成器对象。
  • 是什么让你认为它没有达到?
  • 在没有达到yield的情况下,为什么“函数”仍然充当生成器?
  • @AliSAIDOMAR yield 在函数中的任何位置的存在都会将 整个 的东西一直变成一个生成器。永远达不到收益也没关系。

标签: python generator


【解决方案1】:

yield 在函数体中的存在会将其变成生成器函数,而不是普通函数。在生成器函数中,使用return 是一种表示“生成器已结束,没有更多元素”的方式。通过将生成器方法的第一条语句设为return str_in,可以保证生成器不会返回任何元素。

正如评论中提到的,返回值 用作生成器结束时引发的StopIteration 异常的参数。见:

>>> gen = simple_gen_function("hello", "foo")
>>> next(gen)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration: hello

如果您的def 中有yield,它就是一个生成器!

在 cmets 中,提问者提到他们认为函数在执行 yield 语句时动态地变成了生成器。但这不是它的工作原理!决定是在代码执行之前做出的。如果 Python 在您的 def 下的任何地方找到 yield,它会将 def 转换为生成器函数。

请看这个超浓缩的例子:

>>> def foo():
...     if False:
...         yield "bar"
...     return "baz"
>>> foo()
<generator object foo at ...>
>>> # The return value "baz" is only exposed via StopIteration
>>> # You probably shouldn't use this behavior.
>>> next(foo())
Traceback (most recent call last):
  ...
StopIteration: baz
>>> # Nothing is ever yielded from the generator, so it generates no values.
>>> list(foo())
[]

【讨论】:

  • 谢谢,我相信这是“yield”语句将函数变成生成器的“范围”。
猜你喜欢
  • 2021-12-14
  • 2020-10-30
  • 2020-04-22
  • 1970-01-01
  • 2020-05-28
  • 1970-01-01
  • 2020-01-28
  • 2014-03-10
  • 2016-03-21
相关资源
最近更新 更多