为何Python迭代器采用StopIteration而非IsDone()方法?迭代器协议问询
契合Python的EAFP编程范式
Python核心设计理念之一是"请求原谅比请求许可更容易"(EAFP),与之相对的是"三思而后行"(LBYL)。IsDone()属于LBYL模式,要求每次迭代前先检查状态;而StopIteration则是EAFP的体现——直接调用next()获取元素,直到异常抛出时自然终止迭代。这种方式更符合Python代码的惯用写法,比如for循环就是自动处理该异常,无需开发者手动编写检查逻辑。消除竞态条件
如果使用IsDone(),在多线程环境或者迭代器内部状态可能被外部修改的场景下,会出现"检查时存在元素,但调用next()时元素已耗尽"的竞态问题。而StopIteration的方式保证了next()操作的原子性:要么返回有效元素,要么抛出异常,不存在中间状态的歧义。简化迭代器实现
迭代器只需实现__next__()方法即可,无需额外维护判断状态的逻辑。对于生成器这类动态生成元素的场景(比如逐行读取文件、实时计算序列),提前判断"是否还有下一个元素"本身就不现实——生成器无法预知后续是否还能产生元素,只能在无法生成时抛出异常。这种设计让迭代器的实现逻辑更简洁,降低了开发者的负担。异常开销并非核心问题
Python对StopIteration异常做了专门优化,比如for循环会高效捕获该异常,不会产生明显的性能损耗。反而如果每次迭代都调用IsDone(),额外的函数调用开销在处理大量元素时,累积成本可能高于单次异常的开销。所谓"异常开销高"的顾虑,在正常迭代结束的场景下并不成立。
内容的提问来源于stack exchange,提问作者Pavel

