Can __iter__ be used as a classmethod?

Bjorn Pettersen BPettersen at
Mon Mar 3 21:49:06 CET 2003

I would like to be able to traverse the content of a class (not an
instance) using a regular for loop: "for item in MyClass:...". I can't
seem to get it to work however. I've got the follwing class:

 class ClassIter(object):
    vals = ['a', 'b', 'c']

    def __iter__(cls):
        print 'iter'
        return cls.items()
    __iter__ = classmethod(__iter__)

    def items(cls):
        print 'items'
        for item in cls.vals:
            yield item
    items = classmethod(items)

if I say:

  for x in ClassIter.items(): ...

it works and 'items' is printed out once as expected. If I change it to:

  for x in ClassIter: ...

it fails with "TypeError: iteration over non-sequence" on that line, and
'iter' is never printed. Finally, if I change it to:

  for x in ClassIter.__iter__(): ...

it works (but is not very useful :-)

I've read LibRef 2.2.5 and also RefMan 3.3, and I can't see any
limitations mentioned on which objects can implement __iter__(), or
other __xx__ methods (I haven't found any that work so far). I did
notice "...if a class defines a method named __getitem__(), and x is an
instance of this class, then x[i]...", but I read that as saying "it
definitely works for instance", and not "this only works for instances"

Just for fun I tried a couple more, with the same result.

  get = classmethod(__getitem__) -> (vanilla getitem) SystemError 999: 
                                     bad argument to internal function
  def adder(cls, other):
      return `cls` + `other`
  __add__ = classmethod(adder)    -> TypeError: unsupported operand
                                     for +: 'type' and 'type'
  add = classmethod(adder)        -> works.

Is this a bug or am I missing something (as far as I can tell, I can't
get around this with metaclasses either...)

-- bjorn

More information about the Python-list mailing list