列表理解抛出 RuntimeError
list-comprehension throws a RuntimeError
为什么这段代码运行良好,不抛出异常?
def myzip(*args):
iters = [iter(arg) for arg in args]
try:
while True:
yield tuple([next(it) for it in iters])
except StopIteration:
return
for x, y, z in myzip([1, 2], [3, 4], [5, 6]):
print(x, y, z)
但是如果这一行
yield tuple([next(it) for it in iters])
替换为
yield tuple(next(it) for it in iters)
然后一切都停止工作并抛出 RuntimeError
?
这是 Python 3.5 中引入的功能,而不是错误。根据 PEP-479,当从生成器内部引发 StopIteration
时,RuntimeError
是 re-raised,这样基于生成器的迭代现在只能在生成器 returns,此时引发 StopIteration
异常以停止迭代。
否则,在 Python 3.5 之前,生成器中任何地方引发的 StopIteration
异常将停止生成器而不是传播,因此在以下情况下:
a = list(F(x) for x in xs)
a = [F(x) for x in xs]
如果 F(x)
在迭代期间的某个时刻引发 StopIteration
异常,前者将得到截断的结果,这使得调试变得困难,而后者会传播从 F(x)
。该功能的目标是使两个语句的行为相同,这就是更改影响生成器而不影响列表理解的原因。
为什么这段代码运行良好,不抛出异常?
def myzip(*args):
iters = [iter(arg) for arg in args]
try:
while True:
yield tuple([next(it) for it in iters])
except StopIteration:
return
for x, y, z in myzip([1, 2], [3, 4], [5, 6]):
print(x, y, z)
但是如果这一行
yield tuple([next(it) for it in iters])
替换为
yield tuple(next(it) for it in iters)
然后一切都停止工作并抛出 RuntimeError
?
这是 Python 3.5 中引入的功能,而不是错误。根据 PEP-479,当从生成器内部引发 StopIteration
时,RuntimeError
是 re-raised,这样基于生成器的迭代现在只能在生成器 returns,此时引发 StopIteration
异常以停止迭代。
否则,在 Python 3.5 之前,生成器中任何地方引发的 StopIteration
异常将停止生成器而不是传播,因此在以下情况下:
a = list(F(x) for x in xs)
a = [F(x) for x in xs]
如果 F(x)
在迭代期间的某个时刻引发 StopIteration
异常,前者将得到截断的结果,这使得调试变得困难,而后者会传播从 F(x)
。该功能的目标是使两个语句的行为相同,这就是更改影响生成器而不影响列表理解的原因。