如何对collections.Iterator进行子类化?
根据关于抽象基类(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 个回答
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
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
,具体可以参考这个Python 3的文档。(记得查看正确的版本哦!)
>>> 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__()
引入的。