编程Python后端开发者

在Python中,for-in循环是如何工作的?为了支持这个机制,提供了什么基础架构,当我们遍历自定义对象时,"在引擎盖下"发生了什么?

用 Hintsage AI 助手通过面试

答案。

Python中的for-in循环是通过迭代协议实现的,该协议基于两个特殊方法:__iter__()__next__()。当循环开始时,Python调用iter(obj)(寻找__iter__方法)。如果返回一个实现了__next__()的迭代器对象,循环便开始调用该方法以获取每一个接下来的元素。

如果元素成功返回,迭代将继续。当抛出StopIteration异常时,循环将结束。

自定义迭代器示例:

class Counter: def __init__(self, low, high): self.current = low self.high = high def __iter__(self): return self def __next__(self): if self.current > self.high: raise StopIteration else: self.current += 1 return self.current - 1 for num in Counter(1, 3): print(num) # 输出 1, 2, 3

细微差别: 许多标准的Python结构实现了迭代器协议;您可以轻松地让自己的对象也这样。

反向提问。

可以在任何Python对象上使用for-in循环吗?可迭代对象与迭代器有什么区别?

答案: 不,for-in循环要求对象是可迭代的,也就是说,实现了返回迭代器的__iter__()方法(带有__next__()方法的对象)。迭代器通过__iter__()返回自身,而可迭代对象则不返回。

示例:

lst = [1, 2, 3] iterator = iter(lst) print(hasattr(lst, '__iter__')) # True print(hasattr(iterator, '__next__')) # True(迭代器) print(hasattr(lst, '__next__')) # False(不是迭代器)

由于对主题细微差别的无知而导致的实际错误示例。


故事

项目: 大文件处理。

问题: 在项目中尝试重复遍历文件对象(逐行迭代文件)两次,而不显式打开新文件 — 在第二次迭代时没有获取到任何行(指针已经在文件末尾!)。


故事

项目: 将自定义集合类与框架集成。

问题: 类仅实现了__getitem__,而未实现__iter__,不兼容生成器和标准循环(for)。因此,第三方库出现了问题,期待得到一个迭代器。


故事

项目: 在自定义集合上使用map/filter。

问题: 自定义列表类未实现__iter____next__,与许多标准Python函数不兼容,这在集成测试后才显现出来,并且需要重大重构。