user3457927
user3457927

Reputation: 11

Loop over some variables of a class in Python

I know how I can loop over all variables of a class, but what if I just want to loop over some of them?

class MyClass:
    def __init__(self,var1,var2,var3,var4):
        self.var1 = "foo"
        self.var2 = "bar"
        self.var3 = "spam"
        self.var4 = "eggs"

items_to_loop = ("var2","var4")
for item in items_to_loop:
    print(item, MyClass.(item))

Doesn't work. How do I do this?

Upvotes: 1

Views: 2249

Answers (3)

Anurag Uniyal
Anurag Uniyal

Reputation: 88727

I think you want to loop over all variables of instance of that class, because self.var1 doesn't belong to class but the instance of it

To loop through named attributes of an object you can do this

for var in list_of_vars:
    getattr(obj, var)

e.g.

class MyClass:
    def __init__(self):
        self.var1 = "foo"
        self.var2 = "bar"
        self.var3 = "spam"
        self.var4 = "eggs"

obj = MyClass()
for var in vars(obj):
    print(var, getattr(obj, var))

will output:

('var4', 'eggs')
('var1', 'foo')
('var3', 'spam')
('var2', 'bar')

Upvotes: 1

Larry Lustig
Larry Lustig

Reputation: 50970

First, you need to understand the difference between a class, and an instance of a class (that is, an object).

In your code, MyClass does not contain attributes with the names var1..var4. However, if you create an instance of the class, that instance will contain those attributes. You can then access those attributes using hasattr to check if such an attribute exists and getattr to find its value:

my_object = MyClass()
for attr_name in ('var1', 'var2'):
    if hasattr(my_object, attr_name):
       print  getattr(my_object, attr_name)

Note that classes themselves are allowed to have attributes, but they're declared and behave differently from instance attributes:

 class MyClass(object):

      class_var1 = 'Hello'
      class_var2 = "Goodbye'

      def __init__(self, var1, var2):
           self.var1 = var1
           self.var2 = var2

Now, MyClass has singleton attributes class_var1, class_var2 which will be the same no matter how many objects of type MyClass you create, while each one of those objects will have attributes called var1 and var2 and those values can be different for each instance.

Upvotes: 3

mgilson
mgilson

Reputation: 309831

Can I urge you to change the structure of your data? Something like:

class MyClass:

    def __init__(self,var1,var2,var3,var4):
        self.var = ["foo", "bar", "spam", "eggs"]

is much cleaner. You can see the association of the various pieces of data right away and it becomes trivial to iterate over all of them. In this case, you can even do something like:

for item in instance.var[1::2]:
    ...

Of course, if you're just using those as a very simple example and your attributes really aren't associated, but you want to loop over a group of them anyway, then the way to do it is getattr:

for name in items_to_loop:
    value = getattr(instance, name)
    ...

Or, if you'll do it often, you could use operator.attrgetter:

getter = operator.attrgetter(*items_to_loop):
for value in getter(instance):
    ...

Upvotes: 0

Related Questions