深度讨论Python for循环
作者的其他文章推荐:强化学习再受关注!
for循环使用于遍历可迭代对象的Python语句,工作原理如下:
# for 循环
for item in iterable:
print(item)
# 等价于
iterator = iter(iterable) # 获取迭代器
while True:
try:
item = next(iterator) # 获取下一个元素
print(item)
except StopIteration:
break # 迭代结束
-
调用
iter()
函数,获取可迭代对象的迭代器。(注:iter()函数接收一个可迭代对象作为参数,返回一个迭代器,此迭代器正是这个可迭代对象的__iter_
返回的迭代器)。 -
调用迭代器的
__next__()
方法,获取下一个元素。 -
将元素赋值给循环变量item,并执行循环体。
-
重复步骤 2 和 3,直到迭代器抛出
StopIteration
异常,循环结束。
__getitem___
在第一节魔法函数中提到实现了__getitem__
的对象可以使用索引取值,如x[0]。此外这种对象还可被用于for循环!
Python 的 for
循环在尝试迭代一个对象时,会按照以下顺序进行:
-
如果对象实现了
__iter__
方法,调用__iter__
方法获取迭代器。 -
如果对象没有实现
__iter__
方法,但实现了__getitem__
方法,Python 会尝试使用__getitem__
方法创建一个默认的迭代器(然后就和4.1中一样了),这个默认的迭代器(对__next_
的实现)会从索引0
开始,依次调用__getitem__
方法获取元素,直到抛出IndexError
或StopIteration
异常。- 从索引
0
开始,调用__getitem__(0)
。 - 如果成功返回值,则继续调用
__getitem__(1)
,即for循环会自增索引 - 依次类推,直到
__getitem__
方法抛出IndexError
异常(这个异常要不要显式地抛出要看代码逻辑了),表示没有更多元素可以访问
- 从索引
-
如果对象既没有实现
__iter__
方法,也没有实现__getitem__
方法,会抛出TypeError
异常。