当执行for i in
o时,实际上是调用了iter(o),也就是o.__iter__,返回一个iterator对象。所谓的iterator对象,就是有个next()方
法的对象(归功于duck
typing,我们不需要一个iterator类型,__iter__和next也不一定要定义在类里,而是可以后“粘”上)。next方法的
convention是,每执行一次就返回下一个值(因此它要自己记录状态,通常是在iterator对象上记录),直到没有值的时候raise
StopIteration。
class MyClass():
data1 = 1
data2 = 2
data3 = 3
def __iter__(self):
# in reverse order
return MyIterator(self.data3, self.data2, self.data1);
class MyIterator():
index = 0
def __init__(self, data1, data2, data3):
self.data = (data1, data2, data3)
def next(self):
if self.index > len(self.data) - 1:
raise StopIteration()
else:
temp = self.data[self.index]
self.index += 1
return temp
for i in MyClass():
print i
|
从duck typing的角度来说,generators也是iterators,因为它们自己不仅有__iter__方法,还有next方法!所以上例还可以(无比容易的)写成这样:
class MyClass():
data1 = 1
data2 = 2
data3 = 3
def __iter__(self):
# in reverse order
for d in (self.data3, self.data2, self.data1):
yield d
for i in MyClass():
print i
|
关于上面这段代码得说两句。MyClass()当然是生成了实例,而且由于for语句被调用了__iter__,返回的结果正是一个包含yield语句的函数被执行的结果—-一个具有next方法的generator。
转自:%E5%85%B3%E4%BA%8Epython-iterators%E5%92%8Cgenerators/
阅读(1914) | 评论(0) | 转发(0) |