0

there exists following class.

class Reaction(object):
    Var1 = "lorem"
    Var2 = "impsum"
    Var3 = "dolor"

I'd like to iterate over the attributes of this class, like in following code.

for value in Reaction:
    print value

This should produce following output.

lorem
ipsum
dolor

I've already found this topic: How to iterate over a the attributes of a class, in the order they were defined?, but it doesn't really help me.

How can I make my class iterable?

EDIT: I thought of something similar like in this post: Build a Basic Python Iterator.

Community
  • 1
  • 1
wewa
  • 1,518
  • 1
  • 13
  • 31

3 Answers3

3

If you really need an object whose members are accessible via dot notation but you still want to iterate through them, you need a namedtuple.

Reaction = collections.namedtuple('Reaction', ['Var1', 'Var2', 'Var3'])
reaction = Reaction('lorem', 'ipsum', 'dolor')
for value in reaction:
    print value
Daniel Roseman
  • 567,968
  • 59
  • 825
  • 842
  • Sorry I forgot to mention that I use Python version 2.5.1 and there `collections` doesn't have the method `namedtuple` – wewa Jul 25 '12 at 11:34
1

First off, what you are trying is a little unusual - normally, a dict is used for this kind of thing

Reaction = {
   var1: "Lorem",
   var2: "Ipsum",
   var3: "Dolor"
}

If for some reason you still prefer your method, you can use inspect.getmembers(). A helper function could look like this

def attributes(class_):
    for name, value in inspect.getmembers(class_):
        if not name.startswith("__"):
             yield name, value

Then you can do

for name, value in attributes(Reactor):
    # do stuff
Otto Allmendinger
  • 26,468
  • 7
  • 65
  • 79
1
>>> for k, v in Reaction.__dict__.iteritems():
...     if not k.startswith('__'):
...         print v
... 
lorem
dolor
impsum

Or better:

>>> import inspect
>>> class Reaction(object):
...     Var1 = "lorem"
...     Var2 = "impsum"
...     Var3 = "dolor"
...     def __iter__(self):
...         return (v for k, v in inspect.getmembers(self) if not k.startswith('__'))
... 
>>> for value in Reaction():
...     print value
... 
lorem
impsum
dolor
applicative_functor
  • 4,706
  • 2
  • 20
  • 33