Python中仅含__iter__方法的可迭代类实例解析与代码解读
解析仅实现
__iter__方法的Python可迭代对象工作原理及示例逻辑 先把两个核心概念掰明白,别搞混:
- 可迭代对象:只要实现了
__iter__方法的对象就是可迭代对象,它的核心职责是返回一个迭代器。 - 迭代器:必须同时实现
__iter__(返回自身)和__next__方法的对象,负责实际的元素遍历、返回下一个元素,直到抛出StopIteration信号终止迭代。
你给出的Vector2d类就是典型的「只实现__iter__的可迭代对象」,它自己没写__next__却依然能被迭代——秘密全在它的__iter__方法里:
类的__iter__方法核心逻辑
def __iter__(self): return (i for i in (self.x, self.y))
这里返回的是一个生成器表达式,而生成器本身就是Python内置的迭代器!它自带了__next__方法和迭代终止逻辑,所以Vector2d根本不需要自己写__next__——把迭代的具体工作丢给生成器就行,类只需要提供要迭代的数据源(也就是self.x和self.y)。
示例代码逐行执行拆解
我们一步步看代码跑起来的完整流程:
实例化对象:
v=Vector2d(1,2)
调用__init__方法,把传入的1和2转成浮点数,赋值给v.x和v.y,此时v的x是1.0,y是2.0。解包赋值:
x1,x2=v
Python遇到序列解包时,会自动调用iter(v)获取迭代器(也就是调用v.__iter__()返回的生成器),然后连续调用next()方法:- 第一次
next()取出生成器里的第一个元素1.0,赋值给x1 - 第二次
next()取出第二个元素2.0,赋值给x2
当生成器元素取完,会自动抛出StopIteration,Python捕获这个信号后结束解包操作。
- 第一次
显式获取迭代器:
iv=iter(v)
手动调用iter()函数,同样触发v.__iter__(),返回一个全新的生成器对象,赋值给iv。手动迭代取值:
print(next(iv))和print(next(iv))- 第一次调用
next(iv):生成器返回第一个元素1.0,打印输出 - 第二次调用
next(iv):生成器返回第二个元素2.0,打印输出
如果再调用一次next(iv),生成器就会抛出StopIteration异常,因为已经没有元素可以返回了。
- 第一次调用
总结一下:这个Vector2d类通过让__iter__返回一个内置的生成器迭代器,完美遵守了Python的迭代协议,所以它的实例可以被for循环、解包等所有迭代场景支持,不用自己写复杂的__next__逻辑。
内容的提问来源于stack exchange,提问作者jmakov




