Iterate over object attributes in python


I have a python object with several attributes and methods. I want to iterate over object attributes.

class my_python_obj(object):

    def method1(self, etc, etc):

I want to generate a dictionary containing all of the objects attributes and their current values, but I want to do it in a dynamic way (so if later I add another attribute I don"t have to remember to update my function as well).

In php variables can be used as keys, but objects in python are unsuscriptable and if I use the dot notation for this it creates a new attribute with the name of my var, which is not my intent.

Just to make things clearer:

def to_dict(self):
    """this is what I already have"""
    d["attr1"]= self.attr1
    d["attr2"]= self.attr2
    d["attr3"]= self.attr3
    return d


def to_dict(self):
    """this is what I want to do"""
    for v in my_python_obj.attributes:
        d[v] = self.v
    return d

Update: With attributes I mean only the variables of this object, not the methods.

Answer rating: 275

Assuming you have a class such as

>>> class Cls(object):
...     foo = 1
...     bar = "hello"
...     def func(self):
...         return "call me"
>>> obj = Cls()

calling dir on the object gives you back all the attributes of that object, including python special attributes. Although some object attributes are callable, such as methods.

>>> dir(obj)
["__class__", "__delattr__", "__dict__", "__doc__", "__format__", "__getattribute__", "__hash__", "__init__", "__module__", "__new__", "__reduce__", "__reduce_ex__", "__repr__", "__setattr__", "__sizeof__", "__str__", "__subclasshook__", "__weakref__", "bar", "foo", "func"]

You can always filter out the special methods by using a list comprehension.

>>> [a for a in dir(obj) if not a.startswith("__")]
["bar", "foo", "func"]

or if you prefer map/filters.

>>> filter(lambda a: not a.startswith("__"), dir(obj))
["bar", "foo", "func"]

If you want to filter out the methods, you can use the builtin callable as a check.

>>> [a for a in dir(obj) if not a.startswith("__") and not callable(getattr(obj, a))]
["bar", "foo"]

You could also inspect the difference between your class and its instance object using.

>>> set(dir(Cls)) - set(dir(object))
set(["__module__", "bar", "func", "__dict__", "foo", "__weakref__"])