How to Get a List of Class Attributes in Python

14 Jan

The other day, I was trying to figure out if there was an easy way to grab a class’s defined attributes (AKA “instance variables”). The reason was that we were using the attributes we created to match up with the fields in a file we parse. So basically we read a file line-by-line and each line can be split into 150+ pieces that need to be mapped to the fields we create in the class. The catch is that we recently added more fields to the class and there’s a check in the code that is hard-coded with the number of fields that should be in the file. Thus, when I added more fields, it broke the check. I hope that all made sense. Now you know the background, so we can move on. I found three different ways to accomplish this, so we’ll go from the most complex to the simplest.

As most Python programmers should know, Python provides a handy little builtin called dir. I can use that on a class instance to get a list of all the attributes and methods of that class along with some inherited magic methods, such as ‘__delattr__’, ‘__dict__’, ‘__doc__’, ‘__format__’, etc. You can try this yourself by doing the following:
x = dir(myClassInstance)
However, I don’t want the magic methods and I don’t want the methods either. I just want the attributes. To make everything crystal clear, let’s write some code!
########################################################################
class Test:
“”””””

#———————————————————————-
def __init__(self):
self.varOne = “”
self.varTwo = “”
self.varThree = “”

#———————————————————————-
def methodOne(self):
“”””””
print “You just called methodOne!”

#———————————————————————-
if __name__ == “__main__”:
t = Test()
What we want to get is a list that only contains self.varOne, self.varTwo and self.varThree. The first method that we will look at is using Python’s inspect module.
import inspect
variables = [i for i in t.__dict__ if not inspect.ismethod(i)]
Doesn’t look too complicated, does it? But it requires an import and I’d prefer not to do that. On the other hand, if you need to do introspection, the inspect module is a great way to go. It’s quite powerful and can tell you lots of wonderful things about your class or one you didn’t even write. You’ll note that I’m a magic method from the class: __dict__. We’ll actually be using it in every solution. Anyway, the next easiest way that I found was to use Python’s callable builtin:
variables = [i for i in t.__dict__ if not callable(i)]
You can read more about callable in the Python docs. Basically all that callable does is return a True or False depending on whether or not the object you passed it is callable. Methods are callable, variables are not. Thus we loop over each item in the class dict and only append them to the list if they are not callable (i.e. not methods). Pretty slick and it doesn’t require any imports! But there’s an even easier way!

It all comes back to the magic method, __dict__. In fact, the solution was staring me in the face. Since we’re dealing with a Python dictionary, we can just call its keys method!
variables = t.__dict__.keys()
The real question now is, should you use a magic method to do this? Most Python programmer will probably frown on it. They’re magic, so they shouldn’t be used unless you’re doing metaprogramming. Personally, I think it’s perfectly acceptable for this use case. Let me know of any other methods that I’ve missed or that you think are better.

Resources
•StackOverflow: List attributes of an object
•StackOverflow: Python : Assert that variable is instance method?

from Planet Python http://www.blog.pythonlibrary.org/2013/01/11/how-to-get-a-list-of-class-attributes/

About these ads

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 76 other followers

%d bloggers like this: