How to Get a List of Class Attributes in Python

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 dir(t) 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. Anyway, the next easiest way that I found was to use Python's callable builtin:

variables = [i for i in dir(t) 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!

The simplest way that I found was using the magic method, __dict__. This is built into every class you make unless you override it. 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

Copyright © 2024 Mouse Vs Python | Powered by Pythonlibrary