【问题标题】:Why doesn't this code raise a StopIteration exception?为什么这段代码不引发 StopIteration 异常?
【发布时间】:2022-02-13 01:50:30
【问题描述】:

在这段代码中,我的类名 Iter 包含两个 dunder 方法 __iter____next__。在__iter__method 中,我将self.current 设置为零并返回self。在下一个方法中,我增加 self.current += 1。当它达到 10 时,我希望它引发 StopIteration 异常。

class Iter:
    def __iter__(self):
        self.current = 0
        return self
        
    def __next__(self):
        self.current += 1
        if self.current == 10:
            raise StopIteration
        
        return self.current
        
it = Iter()
for i in it:
    print(i)

【问题讨论】:

  • for-loops 处理StopIteration。如果您想进一步传播它,请改用next()
  • 我相信 StopIteration 只是告诉 for 循环它到达了结尾,它应该退出它。将其更改为ValueError(例如)实际上确实显示了回溯

标签: python iteration stopiteration


【解决方案1】:

您的迭代器已经引发StopIteration,它被for 循环捕获以停止迭代。这就是for 循环正常工作的方式。

如果您添加 print,您可以在迭代器中轻松看到这一点:

    def __next__(self):
        self.current += 1
        if self.current == 10:
            print("raising StopIteration")
            raise StopIteration
1
2
3
4
5
6
7
8
9
raising StopIteration

如果您想在迭代器耗尽后重新引发 StopIteration,一种选择是在 for 循环之后手动引发:

it = Iter()
for i in it:
    print(i)
raise StopIteration
1
2
3
4
5
6
7
8
9
Traceback (most recent call last):
  File "test.py", line 16, in <module>
    raise StopIteration
StopIteration

另一个是改变你进行迭代的方式,这样StopIteration就不会被捕获:

it = iter(Iter())
while True:
    print(next(it))
1
2
3
4
5
6
7
8
9
Traceback (most recent call last):
  File "test.py", line 15, in <module>
    print(next(it))
  File "test.py", line 9, in __next__
    raise StopIteration
StopIteration

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多