英文:
What is the difference between exhausting a generator using "for i in generator" and next(generator)
问题
我想学习如何使用生成器的返回值(但这不是我现在关心的问题)。
经过搜索,他们说当生成器耗尽时,可以从StopIteration
中获取返回值,所以我用以下代码进行了测试:
def my_generator():
yield 1
yield 2
yield 3
return "done"
def exhaust_generator(_gen):
print("===============================================")
print("exhaust_generator")
try:
while True:
print(next(_gen))
except StopIteration as e:
print(f"Return value: '{e.value}'")
def exhaust_generator_iter(_gen):
print("===============================================")
print("exhaust_generator_iter")
try:
for i in _gen:
print(i)
print(next(_gen))
except StopIteration as e:
print(f"Return value: {e.value}")
gen = my_generator()
gen2 = my_generator()
exhaust_generator(gen)
exhaust_generator_iter(gen2)
如您所见,两种耗尽生成器的版本之间的返回值不同,我想知道为什么。
搜索过Google,但没有找到有用的信息。
英文:
I want to learn how to use the return value of a generator (but this not what I'm concerned with now).
After searching, they said that I can get the return value from StopIteration
when the generator is exhausted, so I tested it with the following code:
def my_generator():
yield 1
yield 2
yield 3
return "done"
def exhaust_generator(_gen):
print("===============================================\n")
print("exhaust_generator")
try:
while True:
print(next(_gen))
except StopIteration as e:
print(f"Return value: '{e.value}'")
def exhaust_generator_iter(_gen):
print("===============================================\n")
print("exhaust_generator_iter")
try:
for i in _gen:
print(i)
print(next(_gen))
except StopIteration as e:
print(f"Return value: {e.value}")
gen = my_generator()
gen2 = my_generator()
exhaust_generator(gen)
exhaust_generator_iter(gen2)
===============================================
exhaust_generator
1
2
3
Return value: 'done'
===============================================
exhaust_generator_iter
1
2
3
Return value: None
As you can see, the return value is different between the two versions of exhausting the generator and I wonder why.
Searched google but it has not been helpful.
答案1
得分: 5
在你的第一个示例中,使用while
时,你捕获了生成器在最初耗尽时引发的第一个StopIteration
异常。
在你的第二个示例中,使用for
时,你捕获了一个后续的 StopIteration
异常,这是因为在生成器已经被for
循环用尽并捕获了初始异常后,你调用next()
第二次时引发的。
英文:
In your first example with the while
, you're catching the first StopIteration
exception raised by the generator when it's initially exhausted.
In your second example with the for
, you're catching a subsequent StopIteration
exception raised by calling next()
a second time after the generator has already been exhausted (by the for
, which caught that initial exception).
答案2
得分: 2
根据我理解,for
循环内部也会调用 next()
并最终捕获 StopIteration
,以便知道何时停止调用 next()
。
在 exhaust_generator_iter
中,您的 next()
调用然后引发 第二个 StopIteration
但不带传递值。
此Stack Overflow问题 及其答案探讨了从生成器接收 return
值的方法,包括使用实用程序类或依赖注入。
英文:
As far as I understand, the for
loop internally also calls next()
and eventually catches the StopIteration
, so it knows when to stop calling next()
.
Your next()
call in exhaust_generator_iter
then raises a second StopIteration
but without the passed value.
This SO question and its answers explore ways to receive the return
value from a generator, i.a. using a utility class or dependency injection.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论