You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否为Python类而非仅其实例定义__iter__方法?

当然可以实现!在Python里,类本身也是对象(属于type类的实例),所以我们完全可以给类本身定义__iter__方法,而不是只给它的实例定义。下面就用两种方式来实现你的需求:

方式一:自定义迭代器类

先实现一个迭代器类KlassIter,专门用来迭代Klass类的指定属性,然后给Klass添加类级别的__iter__方法:

class KlassIter:
    def __init__(self, klass):
        self._klass = klass
        # 初始化属性名的迭代器
        self._inner_it = iter(klass.iterable_attr_names)
    
    def __next__(self):
        # 每次迭代取出属性名和对应的类属性值
        attr_name = next(self._inner_it)
        return (attr_name, getattr(self._klass, attr_name))
    
    def __iter__(self):
        return self

class Klass:
    iterable_attr_names = {'x', 'y', 'z'}
    x = 5
    y = 6
    z = 7
    def __init__(self):
        pass
    def foo(*args):
        # 'foo' 不在 iterable_attr_names 里,不会被迭代
        return
    
    @classmethod
    def __iter__(cls):
        # 返回迭代器实例,传入当前类本身
        return KlassIter(cls)

测试一下效果:

for item in Klass:
    print(item)

输出(集合是无序的,顺序可能有所不同):

('x', 5)
('z', 7)
('y', 6)

方式二:用生成器简化实现

如果不想单独写迭代器类,用生成器函数可以更简洁地实现同样的功能:

class Klass:
    iterable_attr_names = {'x', 'y', 'z'}
    x = 5
    y = 6
    z = 7
    def __init__(self):
        pass
    def foo(*args):
        return
    
    @classmethod
    def __iter__(cls):
        # 生成器逐个返回属性名和对应的值
        for attr_name in cls.iterable_attr_names:
            yield (attr_name, getattr(cls, attr_name))

这个版本的测试效果和上面完全一致,代码更紧凑,适合简单的迭代场景。

关键说明

  • 这里用@classmethod装饰器是因为__iter__方法需要接收类本身作为第一个参数(cls),当我们直接迭代Klass类时,Python会自动调用这个方法并传入类对象。
  • 迭代的范围由iterable_attr_names控制,不在这个集合里的属性(比如foo)不会被包含在迭代结果中。

内容的提问来源于stack exchange,提问作者Toothpick Anemone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:13:48