如何对collections.Iterator进行子类化?

4
根据ABCs上的文档,我只需要添加一个next方法就可以继承collections.Iterator。因此,我正在使用以下类:
class DummyClass(collections.Iterator):
    def next(self):
        return 1

然而,当我尝试实例化它时,出现了一个错误:
>>> x = DummyClass()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class DummyClass with abstract methods __next__

我猜我做了一些愚蠢的事情,但我无法找出是什么。有人能帮我解决吗?我可以添加一个__next__方法,但我认为那只适用于C类。
2个回答

10

看起来你正在使用Python 3.x版本。你的代码在Python 2.x版本上可以正常运行。

>>> import collections
>>> class DummyClass(collections.Iterator):
...     def next(self):
...         return 1
... 
>>> x = DummyClass()
>>> zip(x, [1,2,3,4])
[(1, 1), (1, 2), (1, 3), (1, 4)]

在 Python 3.x 中,你应该实现 __next__ 而不是 next,具体请参考 py3k 文档 中的表格。(记得阅读正确版本!)
>>> import collections
>>> class DummyClass(collections.Iterator):
...     def next(self):
...         return 1
... 
>>> x = DummyClass()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can’t instantiate abstract class DummyClass with abstract methods __next__
>>> class DummyClass3k(collections.Iterator):
...     def __next__(self):
...         return 2
... 
>>> y = DummyClass3k()
>>> list(zip(y, [1,2,3,4]))
[(2, 1), (2, 2), (2, 3), (2, 4)]

这种变化是由PEP-3114 — 将iterator.next()重命名为iterator.__next__()引入的。

那一定是 Mac 上 Python 2.6.1 的一个 bug。 - Jason Baker
只是为了澄清我的最后一条评论,我确实在运行Python 2.x。这个问题似乎已经在OS X附带的版本之后的某个版本中得到了修复。 - Jason Baker

3

不一定需要从Iterator类继承来使对象可迭代。但在我的情况下,这是必需的,所以我像这样做:

from collections.abc import Iterator

class MyIterator(Iterator):

    def __init__(self, items, property1, property2):
        self.items = items
        self.property1 = property1
        self.property2 = property2
    
    def __iter__(self):
        return self.items.__iter__()

    def __next__(self):
        return self.items.__next__()

测试代码如下:

my_iterator = MyIterator([1, 2, 3], "value 1", 2)

for item in my_iterator:
    print(f'{item} ', end='')
print()
print(my_iterator.property1)
print(my_iterator.property2)

输出结果为:

1 2 3
value 1
2

文档是:collections.abc.Iterator

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接