在尝试实现迭代器时,我对next()感到困惑。我做了一个简单的测试脚本,其中迭代器的工作方式与我预期的一样:
class Object:
def __init__(self, name):
self.name = name
def prin(self):
print self.name
class Some:
def __init__(self):
self.data = list()
def __iter__(self):
return self.SomeIter(self, len(self.data))
def fill(self, obj):
self.data.append(obj)
def printMe(self):
for entry in self:
print entry.name
class SomeIter:
def __init__(self, some, end):
self.index = 0
self.end = end
self.name = some.data[self.index].name
self.data = some.data
def next(self):
if self.index == self.end:
raise StopIteration
else:
self.name = self.data[self.index].name
self.index += 1
return self
########################################################################
someX = Some()
obj1 = Object("A")
obj2 = Object("B")
someX.fill(obj1)
someX.fill(obj2)
someX.fill(obj2)
for obj in someX:
print obj.name
我得到“A B B”作为输出。那很好。但是我还有一个树类的迭代器。next()-方法的工作原理基本相同。我首先更新实例,然后返回它。但是对于树迭代器,第一个元素被跳过。这对我来说是有意义的,因为我只在更新实例之后才返回self。但是为什么在上面的实现中我会得到不同的行为呢?在这种情况下,实例被更新,然后才被返回呢?在
^{pr2}$我比较了两个迭代器的输出结果,它们不同,SomeIter将第一个元素输出两次:
next: A
A
next: A
B
next: B
B
next: B
另一个迭代器不:
next: a
s
next: s
i
next: i
r
next: r
t
next: t
t
next: t
s
next: s
e
next: e
t
next: t
否则“next:a”将出现2次
这对我来说真的没有任何可怕的意义。。。在
看看这些调用和输出:
someXIter = iter(someX)
print someXIter.next().name
print someXIter.next().name
print someXIter.next().name
输出:
next: A
A
next: A
B
next: B
B
使用此代码:
class SomeIter:
def __init__(self, some, end):
self.index = 0
self.end = end
self.name = some.data[self.index].name
self.data = some.data
def next(self):
print "next: ", self.name
if self.index == self.end:
raise StopIteration
else:
self.name = self.data[self.index].name
self.index += 1
return self
为什么这对我来说毫无意义?因为第一次调用next()时,它输出“next:A”,然后更新实例,并打印函数调用的返回值,也就是“A”。哇?为什么不是“B”,因为返回值应该是更新后的实例。在
Python 2.7
要成为迭代器,必须实现迭代器协议:
obj.__iter__
和{obj.__iter__
必须返回self
StopIteration
被引发,对obj.next()
(next(obj)
)的后续调用必须引发StopIteration
如果一个类只定义
__iter__
,__iter__
必须返回一个实现迭代器协议的对象。如果类中的项包含在内建类型中,就像一个列表,__iter___
可以简单地返回iter(list)
。在我想整个概念中隐含的意思是迭代器必须跟踪它在迭代中的位置。在
如果希望对象是具有不同迭代序列的迭代器,可以定义不同的方法来跟踪迭代并前进到下一个项目,然后在
obj.next()
中使用这些方法。在小例子:
使用
^{pr2}$所以也许只要保持
next
简单,并将树遍历逻辑放在不同的方法中。这可能会使测试这种逻辑变得更容易。您可以随时添加不同的行为:我很难理解您的内部类解决方案是如何工作的,但有一点看起来有点不对劲,就是迭代器对象的}应该返回序列/集合中的下一个项。当您迭代一组事物时,迭代应该为单个事物提供服务,而不是迭代器对象的修改实例。在
next
方法返回self,而且似乎{相关问题 更多 >
编程相关推荐