You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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.xself.y)。

示例代码逐行执行拆解

我们一步步看代码跑起来的完整流程:

  1. 实例化对象v=Vector2d(1,2)
    调用__init__方法,把传入的1和2转成浮点数,赋值给v.xv.y,此时v的x是1.0,y是2.0。

  2. 解包赋值x1,x2=v
    Python遇到序列解包时,会自动调用iter(v)获取迭代器(也就是调用v.__iter__()返回的生成器),然后连续调用next()方法:

    • 第一次next()取出生成器里的第一个元素1.0,赋值给x1
    • 第二次next()取出第二个元素2.0,赋值给x2
      当生成器元素取完,会自动抛出StopIteration,Python捕获这个信号后结束解包操作。
  3. 显式获取迭代器iv=iter(v)
    手动调用iter()函数,同样触发v.__iter__(),返回一个全新的生成器对象,赋值给iv

  4. 手动迭代取值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

火山引擎 最新活动