Enumerating Classes in Modules

Jeff Shannon jeff at ccvcorp.com
Thu Nov 18 22:00:01 EST 2004


Rob Snyder wrote:

>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
>  
>

Right.  Forgot about that little detail.  Oops.  :)

>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
>  
>

Be aware that this will fail for new-style classes --

 >>> class O(object):
...     pass
...
 >>> type(O)
<type 'type'>
 >>> type(O).__name__
'type'
 >>>

Unless your required-method name is something that *is* really common 
(i.e. likely to be present in __builtins__ or in other modules imported 
by the plugin module), you're probably better off not trying to check 
the type.  Attempting the lookup won't hurt anything, as long as you 
catch the AttributeError.

 >>> mymodule = __import__('StringIO')
 >>> mymodule
<module 'StringIO' from 'C:\Python22\lib\StringIO.pyc'>
 >>> dir(mymodule)
['EINVAL', 'StringIO', '__all__', '__builtins__', '__doc__', '__file__', 
'__name__', 'test', 'types']
 >>> for item in dir(mymodule):
...     obj = getattr(mymodule, item)
...     try:
...         obj.plugin_init()
...     except AttributeError:
...         print "%s has no attribute 'plugin_init'" % item
...        
EINVAL has no attribute 'plugin_init'
StringIO has no attribute 'plugin_init'
__all__ has no attribute 'plugin_init'
__builtins__ has no attribute 'plugin_init'
__doc__ has no attribute 'plugin_init'
__file__ has no attribute 'plugin_init'
__name__ has no attribute 'plugin_init'
test has no attribute 'plugin_init'
types has no attribute 'plugin_init'
 >>>

So as long as you're fairly careful about selecting your method name, 
there's no reason to bother with typechecking.  And if you *do* need to 
be more specific, then you're probably better off defining a specific 
plugin_base class and requiring all plugin classes to inherit from it 
(enforced with issubclass(), presumably).


>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.
>  
>

Followups are definitely a good thing.  :)

Jeff Shannon
Technician/Programmer
Credit International




More information about the Python-list mailing list