for 循环是对容器进行迭代的过程。
什么是迭代?
迭代就是从某个容器对象中逐个地读取元素,直到容器中没有更多元素为止。
for 循环的步骤是什么?
- 先判断对象是否为可迭代对象,不是的话直接报错,抛出TypeError异常,是的话,调用
__iter__
方法,返回一个迭代器 - 不断地调用迭代器的
__next__
方法,每次按序返回迭代器中的一个值 - 迭代到最后,没有更多元素了,就抛出异常 StopIteration,这个异常 python 自己会处理,不会暴露给开发者
那么,哪些对象支持迭代操作?任何对象都可以吗?
for 循环本质是不断地调用迭代器的__next__
方法,直到有 StopIteration 异常为止,
所以任何可迭代对象都可以作用在for循环中。
弄明白了 for 的执行原理之后,我们就可以实现自己的迭代器用在 for 循环中:
1 class MyRange:
2 def __init__(self, num):
3 self.i = 0
4 self.num = num
5
6 def __iter__(self):
7 return self
8
9 def __next__(self):
10 if self.i < self.num:
11 i = self.i
12 self.i += 1
13 return i
14 else:
15 # 达到某个条件时必须抛出此异常,否则会无止境地迭代下去
16 raise StopIteration()
因为它实现了__next__
方法,所以 MyRange 本身已经是一个迭代器了,所以 __iter__
返回的就是对象本身 self。
现在用在 for 循环中试试:
for i in MyRange(3):
print(i)
# 输出
0
1
2
有没有发现,自定义的 MyRange
功能和内建函数 range
很相似。
综上所述:
for 循环本质是不断地调用迭代器的__next__
方法,直到有 StopIteration 异常为止,所以任何可迭代对象都可以作用在for循环中。