为什么下一次提出'StopIteration',但是'for'是否正常回报? [英] Why does next raise a 'StopIteration', but 'for' do a normal return?

查看:1996
本文介绍了为什么下一次提出'StopIteration',但是'for'是否正常回报?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这段代码中,为什么使用'for'导致没有'StopIteration'
或'for'循环捕获所有异常然后默默退出?
在这种情况下,为什么我们有无关的回报?或者是
提高StopIteration 引起的:返回无

In this piece of code, why does using 'for' result in no 'StopIteration' or is the 'for' loop trapping all exceptions and then silently exiting? In which case, why do we have the extraneous 'return'?? Or is the raise StopIteration caused by: return None?

#!/usr/bin/python3.1
def countdown(n):
    print("counting down")
    while n >= 9:
        yield n
        n -= 1
    return

for x in countdown(10):
    print(x)

c = countdown(10)
next(c)
next(c)
next(c)

假设 StopIteration 被触发: return None
GeneExit何时生成?

Assuming StopIteration is being triggered by: return None. When is GeneratorExit generated?

def countdown(n):
    print("Counting down from %d" % n)
    try:
        while n > 0:
            yield n
            n = n - 1
    except GeneratorExit:
        print("Only made it to %d" % n)

如果我手动执行:

c = countdown(10)
c.close() #generates GeneratorExit??

在哪种情况下为什么我看不到追溯?

In which case why don't I see a traceback?

推荐答案

for 循环显式侦听 StopIteration

语句的的目的是循环遍历迭代器提供的序列,并且异常用于表示迭代器现已完成; for 不会捕获被迭代的对象引发的其他异常,只有那个。

The purpose of the for statement is to loop over the sequence provided by an iterator and the exception is used to signal that the iterator is now done; for doesn't catch other exceptions raised by the object being iterated over, just that one.

那是因为 StopIteration 是正常的预期信号告诉谁正在迭代没有更多的东西要生产。

That's because StopIteration is the normal, expected signal to tell whomever is iterating that there is nothing more to be produced.

一台发电机函数是一种特殊的迭代器;函数完成时确实会引发 StopIteration (即返回时,是的,返回无引发 StopIteration异常)。这是迭代器的要求;他们必须提高 StopIteration 完成后;事实上,一旦 StopIteration 被提出,试图从他们那里获取另一个元素(通过 next(),或者在迭代器上调用 .next()(py 2)或 .__ next __()(py 3)方法必须再次提高 StopIteration

A generator function is a special kind of iterator; it indeed raises StopIteration when the function is done (i.e. when it returns, so yes, return None raises StopIteration). It is a requirement of iterators; they must raise StopIteration when they are done; in fact, once a StopIteration has been raised, attempting to get another element from them (through next(), or calling the .next() (py 2) or .__next__() (py 3) method on the iterator) must always raise StopIteration again.

GeneratorExit 是在其他方向进行通信的例外。你明确关闭一个带有 yield 表达式的生成器,以及Python将该闭包传递给生成器的方式是提高 GeneratorExit 在该函数内部。您在倒计时中明确捕获该异常,其目的是让生成器在关闭时根据需要清理资源。

GeneratorExit is an exception to communicate in the other direction. You are explicitly closing a generator with a yield expression, and the way Python communicates that closure to the generator is by raising GeneratorExit inside of that function. You explicitly catch that exception inside of countdown, its purpose is to let a generator clean up resources as needed when closing.

A GeneratorExit 不会传播给调用者;请参阅 generator.close()文档

A GeneratorExit is not propagated to the caller; see the generator.close() documentation.

这篇关于为什么下一次提出'StopIteration',但是'for'是否正常回报?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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