带返回语句的生成器

Ali*_*MAR 1 python generator

在我的报道中,我对以下案例感到头疼(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' ''
Run Code Online (Sandbox Code Playgroud)

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

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

Dan*_*aro 7

的存在下yield在一个函数体把它变成发电机功能,而不是正常功能。在生成器函数中, usingreturn是一种说法“生成器已经结束,没有更多元素了”。通过将生成器方法的第一条语句设置为 be 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
Run Code Online (Sandbox Code Playgroud)

如果yield在你的任何地方def,它就是一个生成器!

在评论中,提问者提到他们认为在执行 yield 语句时,函数会动态地变成生成器。但这不是它的工作原理!该决定是在代码执行之前做出的。如果 Pythonyield在您的 下任何地方找到 a def,它就会将其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())
[]
Run Code Online (Sandbox Code Playgroud)