gpt4 book ai didi

python - python 生成器函数中引发的 StopIteration 异常处理

转载 作者:行者123 更新时间:2023-12-01 23:15:15 26 4
gpt4 key购买 nike

这是我的生成器函数代码:

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 相同的异常。请帮我改正。

最佳答案

Here is my code version-1 for generating sequence:

for Python 中的循环构造是它已经调用next在迭代器上(它从生成器自动创建)。所以你应该只print(ele)相反。

RuntimeError: generator raised StopIteration

是的,因为你不应该使用明确的 raise StopIteration在发电机中。这是一个用于与 for 通信的工具。循环你没有元素,这只有在你实现 __iter__ 时才需要方法老办法。是的,for循环构造依赖于此异常来确定输入的结束;但是从您的生成器创建的迭代器会自动执行此操作 - 并检查 StopIteration s 在生成器中生成并将它们转换为 RuntimeError ,明确防止你的StopIteration免于跳出循环。

如果底层机器没有那个检查,那么你可以做类似 for i in itertools.chain(my_generator, a_list): 的事情,并且生成器实现引发的异常将强行中断循环(毕竟,循环通过处理该异常退出)并阻止a_list被看见的元素。这不是您希望生成器的行为方式,而且在某种意义上它也是一种安全风险,因此存在检查。

如果你想发出信号表明发电机已完成 yield ing,你所做的是......到达代码的末尾。例如,使用 return ,或者在本例中为 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

关于python - python 生成器函数中引发的 StopIteration 异常处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69037993/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com