next()不能与python中的任何/ all一起播放

我跑了一个bug,今天发生了,因为我使用next()提取一个值,’not found’发出一个StopIteration。

通常会停止程序,但是使用next的函数在all()迭代中被调用,因此所有的都被提前终止并返回True。

这是一个预期的行为吗?有没有样式指南,帮助避免这种事情?

简化示例:

def error(): return next(i for i in range(3) if i==10)
error() # fails with StopIteration
all(error() for i in range(2)) # returns True
虽然这是在编写时的现有版本的Python的预期行为,它被安排在下一个几点版本的Python 3.x的过程中改变 – 引用PEP 479

The interaction of generators and StopIteration is currently somewhat surprising, and can conceal obscure bugs. An unexpected exception should not result in subtly altered behaviour, but should cause a noisy and easily-debugged traceback. Currently, StopIteration raised accidentally inside a generator function will be interpreted as the end of the iteration by the loop construct driving the generator.

使用Issue 22906Issue 22906测试代码,应用到最新的Python trunk,我们得到以下结果:

Python 3.5.0a0 (default:651aa21433ba+, Feb  2 2015, 21:01:26) 
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 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 "<stdin>", line 1, in <genexpr>
  File "<stdin>", line 1, in error
StopIteration

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: generator raised StopIteration

可以看到,在将来的Python版本中,StopIteration将不再在这种情况下“冒泡”,而是转换为RuntimeError。

这个新行为被计划为是可选的,在Python 3.5中添加一个from __future__ import generator_stop import,并成为Python 3.7中的默认行为。

http://stackoverflow.com/questions/28288871/next-doesnt-play-nice-with-any-all-in-python

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:next()不能与python中的任何/ all一起播放