python中所有的迭代环境都会先尝试__iter__方法,再尝试__getitem__,只有在对象不支持迭代协议时,才会尝试索引
迭代器
- 迭代器:可以被next()函数调用并不断返回下一个值的对象称为迭代器
- 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束;迭代器只能往前不会后退。
- 迭代器有两个基本的方法:iter()和next()
- 可以使用isinstance()判断一个对象是否是迭代器对象(iterator)
- python3中 range(n)生成的是迭代器对象;Python2中xrange(n)生成的才是迭代器对象
将类(class)改造成迭代器
迭代环境是通过调用内置函数iter去尝试寻找__iter__方法来实现的,而这种方法应该返回一个迭代器,如果没有找到__iter__方法,python会改用__getitem__机制
- 把一个类作为一个迭代器使用需要在类中实现两个方法 __iter__() 与 __next__() 。
- __iter__() 方法返回一个特殊的迭代器对象, 这个迭代器对象实现了 __next__() 方法并通过 StopIteration 异常标识迭代的完成。
- __next__() 方法(Python 2 里是 next())会返回下一个迭代器对象。
- 例如 类test:
class test(): def __init__(self,data=1): self.data = data def __iter__(self): return self # 唯一需要注意的就是__next__中必须控制iterator的结束条件,不然就死循环了 def __next__(self): if self.data > 7: raise StopIteration else: self.data+=1 return self.data for item in test(2): print(item)
out:
3
4
5
6
7
8
for ... in ...这个语句其实做了两件事:第一:获得一个可迭代器,即调用了 __iter__()函数,第二:循环过程,即循环调用__next__()函数
1. 可用于for循环的数据类型有一下几种:
(1)集合数据类型:list, tuple, dict, set, str, bytes
(2)generator(数据结构):生成器、带yield的generator function
2. 可迭代对象(iterable):可直接作为for循环的对象,统称为可迭代对象。python从可迭代对象中获取迭代器。但凡是可以返回一个迭代器的对象都可称之为可迭代对象
对于test这个类来说,它定义了__iter__和__next__函数,所以是一个可迭代的类,也可以说是一个可迭代的对象(Python中一切皆对象)。
特殊例子:
如果去掉__itet__()函数,就不能用于for ... in .....循环中
class test():
def __init__(self,data=1):
self.data = data
#def __iter__(self):
# return self
# 唯一需要注意下的就是__next__中必须控制iterator的结束条件,不然就死循环了
def __next__(self):
if self.data > 7:
raise StopIteration
else:
self.data+=1
return self.data
for item in test(2):
print(item)
运行报错:
TypeError: 'test' object is not iterable
但是可以通过下面的方式调用:
class test():
def __init__(self,data=1):
self.data = data
#def __iter__(self):
# return self
# 唯一需要注意下的就是__next__中必须控制iterator的结束条件,不然就死循环了
def __next__(self):
if self.data > 7:
raise StopIteration
else:
self.data+=1
return self.data
#for item in test(2):
# print(item)
T = test(2)
# 由于 print(T.__next__())每次只能输出一个值,给它加个遍历次数就可以了,不过相比带有 __iter__还是有点麻烦
for i in range(6):
print(T.__next__())
out:
3
4
5
6
7
8
iter()函数与next()函数:iter
是将一个对象(列表)变成迭代器对象,使用next
函数式取迭代器中的下一个数据
it = iter([1, 2, 3, 4, 5])
# 循环:
while True:
try:
# 获得下一个值:
x = next(it)
print(x)
except StopIteration:
# 遇到StopIteration就退出循环
break
out:
1
2
3
4
5
Reference:
python3_迭代器与生成器__ / __iter__() / __next__() / yield / next() / iter()
python 运算符重载迭代器对象__iter__,__next__