在我的报道中,我对以下案例(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 可以解决这个问题。
函数体中 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
,那么它就是一个生成器!
在评论中,提问者提到当执行 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())
[]