虽然这是 Python 3.6 及以下版本中的默认行为,但它被认为是语言中的错误,并计划在 Python 3.7 中进行更改,以便引发异常。
正如PEP 479所说:
StopIteration
生成器和当前的交互有点令人惊讶,并且可以隐藏晦涩的错误。意外的异常不应导致行为的细微改变,而应引起嘈杂且易于调试的回溯。目前,StopIteration
在生成器函数中意外引发将被驱动生成器的循环构造解释为迭代的结束。
从 Python 3.5 开始,可以将默认行为更改为为 3.7 安排的行为。这段代码:
# gs_exc.py
from __future__ import generator_stop
def error():
return next(i for i in range(3) if i==10)
all(error() for i in range(2))
…引发以下异常:
Traceback (most recent call last):
File "gs_exc.py", line 8, in <genexpr>
all(error() for i in range(2))
File "gs_exc.py", line 6, in error
return next(i for i in range(3) if i==10)
StopIteration
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "gs_exc.py", line 8, in <module>
all(error() for i in range(2))
RuntimeError: generator raised StopIteration
在没有导入的Python 3.5 和 3.6中__future__
,会引发警告。例如:
# gs_warn.py
def error():
return next(i for i in range(3) if i==10)
all(error() for i in range(2))
$ python3.5 -Wd gs_warn.py
gs_warn.py:6: PendingDeprecationWarning: generator '<genexpr>' raised StopIteration
all(error() for i in range(2))
$ python3.6 -Wd gs_warn.py
gs_warn.py:6: DeprecationWarning: generator '<genexpr>' raised StopIteration
all(error() for i in range(2))