Enumerating Classes in Modules

Rob Snyder arkham at gmail.com
Fri Nov 19 03:22:25 CET 2004


Rob Snyder wrote:

> Jeff Shannon wrote:
> 
>> Rob Snyder wrote:
>> 
>>>Greetings -
>>>
>>>I have a situation where I need to be able to have a Python function that
>>>will take all the modules in a given directory and find all the classes
>>>defined in these modules by name. Ultimately, I would need to loop
>>>through all of these, instantiating each of the classes in turn and
>>>calling a pre-known method of each.
>>>
>>>Finding the name of each module is not a problem, but loading the classes
>>>out the module once I know the name is where I'm lost.
>>>  
>>>
>> 
>> Hm.  Any reason to not simply import the module (using the __import__()
>> function), going through all names in that module's namespace, and
>> attempting to call the method on them?  (Catching AttributeErrors as
>> necessary, of course.)
>> 
>> Something like this (untested, unresearched, and totally off the top of
>> my head):
>> 
>> for modname in nameslist:
>>     plugins[modname] = __import__(modname)
>>     # ....
>>     for item in dir(plugins[modname]):
>>         try:
>>             item.standard_method()
>>         except AttributeError:
>>             pass
>> 
>> If you need something a bit more specific, maybe you could require all
>> plugin classes to be derived from a common subclass, and before calling
>> the standard_method() you could check issubclass(item, plugin_base)...
>> 
>> Jeff Shannon
>> Technician/Programmer
>> Credit International
> 
> Any reason no to? Not other then I couldn't figure it out on my own. :)
> 
> Thanks so much for your help, this will do the trick nicely.
> 
> Rob Snyder

Just in case anyone "follows in my footsteps" and has the same problem I did
- Jeff's answer is pretty much dead on. The only stumbling block I had was
that the dir() returns a list of strings representating the name of the
attributes, and includes things that are not class definitions (e.g.
'--builtins--'). So two modifications are necessary:

1 - use the getattr() function with each item returned by dir() to actually
load the class object
2 - use type() to determine if it really it really is a classobj

For example:
for modname in nameslist:
    plugins[modname] = __import__(modname)
    # ....
    for item in dir(plugins[modname]):
        try:
            a = getattr(plugins[modname],item)
            if (type(a).__name__ == 'classobj'):
                item.standard_method()
        except AttributeError:
            pass
        
(or something similar, you'd probably want to do something with the try...
except).

Again, thanks for the help. I apologize for clogging up people's
newsreaders, I've just found it helpful when poeple post their conculsions
with things, so I wanted to do the same.

Rob



More information about the Python-list mailing list