Iterate over object attributes in python [duplicate] Iterate over object attributes in python [duplicate] python python

Iterate over object attributes in python [duplicate]


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__'])


in general put a __iter__ method in your class and iterate through the object attributes or put this mixin class in your class.

class IterMixin(object):    def __iter__(self):        for attr, value in self.__dict__.iteritems():            yield attr, value

Your class:

>>> class YourClass(IterMixin): pass...>>> yc = YourClass()>>> yc.one = range(15)>>> yc.two = 'test'>>> dict(yc){'one': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], 'two': 'test'}


As mentioned in some of the answers/comments already, Python objects already store a dictionary of their attributes (methods aren't included). This can be accessed as __dict__, but the better way is to use vars (the output is the same, though). Note that modifying this dictionary will modify the attributes on the instance! This can be useful, but also means you should be careful with how you use this dictionary. Here's a quick example:

class A():    def __init__(self, x=3, y=2, z=5):        self.x = x        self._y = y        self.__z__ = z    def f(self):        passa = A()print(vars(a))# {'x': 3, '_y': 2, '__z__': 5}# all of the attributes of `a` but no methods!# note how the dictionary is always up-to-datea.x = 10print(vars(a))# {'x': 10, '_y': 2, '__z__': 5}# modifying the dictionary modifies the instance attributevars(a)["_y"] = 20print(vars(a))# {'x': 10, '_y': 20, '__z__': 5}

Using dir(a) is an odd, if not outright bad, approach to this problem. It's good if you really needed to iterate over all attributes and methods of the class (including the special methods like __init__). However, this doesn't seem to be what you want, and even the accepted answer goes about this poorly by applying some brittle filtering to try to remove methods and leave just the attributes; you can see how this would fail for the class A defined above.

(using __dict__ has been done in a couple of answers, but they all define unnecessary methods instead of using it directly. Only a comment suggests to use vars).