这是我的生成器函数代码:
def fibo():
n1=0
n2=1
while True:
if n1 == 8:
raise StopIteration
else:
yield n1
n1,n2=n2,n1+n2
seq=fibo()
这是我用于生成序列的代码版本 1:
for ele in seq:
print(next(seq))
输出:
1
2
5
RuntimeError: generator raised StopIteration
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
<ipython-input-3-c01815b93e23> in fibo()
5 if n1 == 8:
----> 6 raise StopIteration
7 else:
StopIteration:
The above exception was the direct cause of the following exception:
RuntimeError Traceback (most recent call last)
<ipython-input-3-c01815b93e23> in <module>
11 seq=fibo()
12
---> 13 for ele in seq:
14 print(next(seq))
15
RuntimeError: generator raised StopIteration
我对版本 1 的预期输出:
0
1
1
2
3
5
这是我用于生成序列的代码版本 2:
while True:
try:
print(next(seq))
except StopIteration:
print('This exception is raised in the generator operation defining function. Hence it is handled here.')
break
输出:
0
1
1
2
3
5
RuntimeError: generator raised StopIteration
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
<ipython-input-4-6afe26583a33> in fibo()
5 if n1 == 8:
----> 6 raise StopIteration
7 else:
StopIteration:
The above exception was the direct cause of the following exception:
RuntimeError Traceback (most recent call last)
<ipython-input-4-6afe26583a33> in <module>
16 while True:
17 try:
---> 18 print(next(seq))
19 except StopIteration:
20 print('This exception is raised in the generator operation defining function. Hence it is handled here.')
RuntimeError: generator raised StopIteration
我对版本 2 的预期输出:
0
1
1
2
3
5
This exception is raised in the generator operation defining function. Hence it is handled here.
在第一个版本中, out 不正确并且正在发生异常。在第二个中,除了正确的输出之外,还发生了与版本 1 相同的异常。请帮我纠正这个问题。
这是我用于生成序列的代码版本 1:
点的for
Python中循环结构是,它已经呼吁next
在迭代器(它从自动生成器创建)。所以你应该只是print(ele)
相反。
运行时错误:生成器引发了 StopIteration
是的,因为您不应该raise StopIteration
在生成器中使用显式。这是一个旧的工具,用于向for
循环传达您已用完元素的信息,只有在您以__iter__
老式方式实现方法时才需要这种工具。是的,for
循环构造依赖于这个异常来确定输入的结束;但是从您的生成器创建的迭代器会自动执行此操作 - 并且还会检查StopIteration
生成器中是否存在s 并将它们转换为RuntimeError
, 以防止您StopIteration
跳出循环。
如果底层机器没有那个检查,那么你可以做这样的事情for i in itertools.chain(my_generator, a_list):
,并且生成器实现引发的异常将强行中断循环(毕竟,循环通过处理该异常退出)并防止a_list
元素被看到. 这不是您希望生成器的行为方式,并且在某种意义上也是一种安全风险,因此该检查就在那里。
如果你想发出一个生成器已经完成的信号,yield
你要做的是......到达代码的末尾。例如, with return
, or 在这种情况下break
也可以工作(因为循环之后没有其他内容):
def fibo():
n1, n2 = 0, 1
while True:
if n1 == 8:
break
else:
yield n1
n1, n2 = n2, n1+n2
print('This exception is raised in the generator operation defining function. Hence it is handled here.')
没有发生的原因是您正在尝试捕获StopIteration
(您不应该这样做,因为它会干扰循环的操作!),但例外是(如果您仔细阅读堆栈跟踪,您就会知道)替换为RuntimeError
反而。看上面。
使用上面更正的代码,一切都按预期工作:
>>> list(fibo())
[0, 1, 1, 2, 3, 5]
>>> x = fibo()
>>> for f in x:
... print(f)
...
0
1
1
2
3
5
>>> x = fibo()
>>> while True:
... try:
... print(next(x))
... except StopIteration:
... print('this works as intended - but a for loop is much cleaner')
... break
...
0
1
1
2
3
5
this works as intended - but a for loop is much cleaner
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句