Getting attributes of a class

Mohamed Khamis picture Mohamed Khamis · Jan 30, 2012 · Viewed 260.7k times · Source

I want to get the attributes of a class, say:

class MyClass():
  a = "12"
  b = "34"

  def myfunc(self):
    return self.a

using MyClass.__dict__ gives me a list of attributes and functions, and even functions like __module__ and __doc__. While MyClass().__dict__ gives me an empty dict unless I explicitly set an attribute value of that instance.

I just want the attributes, in the example above those would be: a and b

Answer

Matt Luongo picture Matt Luongo · Jan 30, 2012

Try the inspect module. getmembers and the various tests should be helpful.

EDIT:

For example,

class MyClass(object):
    a = '12'
    b = '34'
    def myfunc(self):
        return self.a

>>> import inspect
>>> inspect.getmembers(MyClass, lambda a:not(inspect.isroutine(a)))
[('__class__', type),
 ('__dict__',
  <dictproxy {'__dict__': <attribute '__dict__' of 'MyClass' objects>,
   '__doc__': None,
   '__module__': '__main__',
   '__weakref__': <attribute '__weakref__' of 'MyClass' objects>,
   'a': '34',
   'b': '12',
   'myfunc': <function __main__.myfunc>}>),
 ('__doc__', None),
 ('__module__', '__main__'),
 ('__weakref__', <attribute '__weakref__' of 'MyClass' objects>),
 ('a', '34'),
 ('b', '12')]

Now, the special methods and attributes get on my nerves- those can be dealt with in a number of ways, the easiest of which is just to filter based on name.

>>> attributes = inspect.getmembers(MyClass, lambda a:not(inspect.isroutine(a)))
>>> [a for a in attributes if not(a[0].startswith('__') and a[0].endswith('__'))]
[('a', '34'), ('b', '12')]

...and the more complicated of which can include special attribute name checks or even metaclasses ;)