基本概念
可迭代对象
是可以通过"for…in…"遍历的对象,需要实现__iter__()的方法,并且这个方法要返回一个迭代器。
迭代器
用来返回数据,需要实现__next__()和__iter__()方法,如果迭代器没有返回值了,next()方法就会抛出一个StopIteration异常。
判断一个对象是否是可迭代对象
from collections import Iterable
# 可迭代对象
ret = [1, 2, 3]
print(isinstance(ret, Iterable))
ret = (1, 2, 3)
print(isinstance(ret, Iterable))
ret = "123"
print(isinstance(ret, Iterable))
# 不可迭代对象
ret = 123
print(isinstance(ret, Iterable))
自定义可迭代对象
实现了__iter__()方法的对象就是可迭代对象
from collections import Iterable
class MyRange(object):
"""
实现了__iter__()方法的类就是可迭代对象
"""
def __iter__(self):
pass
ret = MyRange()
print(isinstance(ret, Iterable))
实现迭代器对象和可迭代对象
分别实现迭代器和可迭代对象,可迭代对象的__iter__()方法返回外部实现的迭代器对象,这样的对象可以被多次迭代。
class MyRangeIterator(object):
"""
迭代器
"""
def __init__(self, start, end):
self.index = start
self.end = end
def __next__(self):
if self.index < self.end:
tmp = self.index
self.index += 1
return tmp
else:
raise StopIteration
def __iter__(self):
return self
class MyRange(object):
"""
可迭代对象
"""
def __init__(self, start, end):
self.start = start
self.end = end
def __iter__(self):
# 每次都重新生成一个迭代器,所以可以进行多次迭代
return MyRangeIterator(self.start, self.end)
ret = MyRange(1, 10)
for i in ret:
print(i)
print("*" * 20)
# 用while模拟for的底层实现
ret_iter = ret.__iter__()
while True:
try:
x = ret_iter.__next__()
print(x)
except StopIteration:
break
一个对象同时作为迭代器和可迭代对象
这样的对象同时实现了__next__()和__iter__()方法,其中__iter__()方法返回了它自己(因为它本身作为了一个迭代器)。但是这样的对象只能被迭代一次,因为self.index已经走到头了,会抛出StopIteration异常。
class MyRange(object):
"""
同时作为可迭代对象和迭代器,只能进行一次迭代
"""
def __init__(self, start, end):
self.start = start
self.end = end
self.index = start
def __iter__(self):
# 这个方法返回一个迭代器
return self
def __next__(self):
if self.index < self.end:
tmp = self.index
self.index += 1
return tmp
else:
raise StopIteration
ret = MyRange(1, 10)
for i in ret:
print(i)
print("*" * 20)
# 因为在for循环中已经把index走到头了,所以下面并不会输出
ret_iter = ret.__iter__()
while True:
try:
x = ret_iter.__next__()
print(x)
except StopIteration:
break