所以我一直在编写迭代器,我认为我理解它们。但是我今晚一直在努力解决一些问题,而且我玩的越多,我就越困惑。
我认为对于迭代器,您必须实现next
和__next__
(或__iter__
)。当你第一次尝试迭代迭代器时,将调用next
方法,然后调用StopIteration
直到class Iter(object):
def __iter__(self):
return iter([2, 4, 6])
def next(self):
for y in [1, 2, 3]:
return y
iterable = Iter()
for x in iterable:
print(x)
被引发。
当我运行此代码时
2 4 6
输出为__iter__
。因此,next
被调用,但不是next
。这似乎与我找到的here文档相符。但那时我脑海里浮现出更多问题。
具体来说,如果它不是next
的实现,那么容器类型和迭代器之间的区别是什么?我如何知道我的课程将以哪种方式对待?最重要的是,如果我想编写一个使用for x in Iter()
时调用UITextBorderStyleNone
方法的类,我该怎么做?
答案 0 :(得分:6)
列表是 iterable ,但它不是迭代器。比较和对比:
>>> type([])
list
>>> type(iter([]))
list_iterator
在列表上调用iter
会创建并返回一个新的迭代器对象,用于迭代该列表的内容。
在你的对象中,你只返回一个列表迭代器,特别是列表[2, 4, 6]
上的迭代器,这样对象就不知道产生元素1,2,3。
def __iter__(self):
return iter([2, 4, 6]) # <-- you're returning the list iterator, not your own
这是一个更基本的实现,符合Python 2中的迭代器协议,它不会因依赖列表迭代器,生成器或任何花哨的东西而混淆。
class Iter(object):
def __iter__(self):
self.val = 0
return self
def next(self):
self.val += 1
if self.val > 3:
raise StopIteration
return self.val
答案 1 :(得分:2)
根据您链接的文档,迭代器的__iter__
方法应该返回自身。所以你的迭代器根本就不是迭代器:当for
调用__iter__
来获取迭代器时,你给它iter([2,4,6])
,但你应该给它self
。
(另外,我不认为您的next
方法符合您的意图:每次调用它都会返回1
,并且永远不会引发StopIteration
。因此,如果你修复了__iter__
,那么你的迭代器将是一个无限流的迭代器,而不是有限列表[1, 2, 3]
。但这是一个副问题。)